### Hello world Plug with Mix.install and Plug.Conn Source: https://plug.hexdocs.pm/readme.html Minimal hello world example using the Cowboy webserver. Installs `:plug` and `:plug_cowboy`, defines a module with `init/1` and `call/2` (implied by `Plug.Conn` import), and returns a 200 response with the body "Hello World from Plug". The `Plug.Conn.send_resp/3` function is used to send the response. ```elixir Mix.install([:plug, :plug_cowboy]) defmodule MyPlug do import Plug.Conn def init(options) do # initialize options options end def call(conn, _opts) do conn |> put_resp_content_type("text/plain") |> send_resp(200, ``` -------------------------------- ### Function: get/1 examples Source: https://plug.hexdocs.pm/Plug.Session.Store.md Gets the store name from an atom or a module. The examples show that CustomStore returns CustomStore and :cookie returns Plug.Session.COOKIE. ```elixir iex> Plug.Session.Store.get(CustomStore) CustomStore ``` ```elixir iex> Plug.Session.Store.get(:cookie) Plug.Session.COOKIE ``` -------------------------------- ### compile/3 example Source: https://plug.hexdocs.pm/Plug.Builder.md Example of using Plug.Builder.compile/3 with a reversed pipeline of plugs, including guards. ```elixir Plug.Builder.compile(env, [ {Plug.Logger, [], true}, # no guards, as added by the Plug.Builder.plug/2 macro {Plug.Head, [], quote(do: a when is_binary(a))} ], []) ``` -------------------------------- ### Function plug example (hello_world_plug) Source: https://plug.hexdocs.pm/ A function plug takes the connection and options as arguments and returns the connection. This example sends a 'Hello world' response. ```elixir def hello_world_plug(conn, _opts) do conn |> put_resp_content_type("text/plain") |> send_resp(200, "Hello world") end ``` -------------------------------- ### Example of the %Plug.Conn{} struct Source: https://plug.hexdocs.pm/ Shows the structure of the Plug.Conn struct with example fields like host and path_info. ```elixir %Plug.Conn{ host: "www.example.com", path_info: ["bar", "baz"], ... } ``` -------------------------------- ### Module plug example (MyPlug) Source: https://plug.hexdocs.pm/ A module plug implements init/1 and call/2. This example shows a minimal module plug that returns the connection unchanged. ```elixir defmodule MyPlug do def init([]), do: false def call(conn, _opts), do: conn end ``` -------------------------------- ### send_file/5 example Source: https://plug.hexdocs.pm/Plug.Conn.md Example call to send_file/5 that sends the file 'README.md' with status 200. ```elixir Plug.Conn.send_file(conn, 200, "README.md") ``` -------------------------------- ### Update lib/my_app/application.ex to supervise Plug.Cowboy Source: https://plug.hexdocs.pm/ Configures the application's supervision tree to start Plug.Cowboy with the MyPlug module on port 4001. This is the core setup for running a Plug pipeline under supervision. ```elixir defmodule MyApp.Application do # See https://hexdocs.pm/elixir/Application.html # for more information on OTP Applications @moduledoc false use Application def start(_type, _args) do # List all child processes to be supervised children = [ {Plug.Cowboy, scheme: :http, plug: MyPlug, options: [port: 4001]} ] # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) end end ``` -------------------------------- ### Module plug example: JSONHeaderPlug Source: https://plug.hexdocs.pm/Plug.md Example of a module plug that implements the Plug behaviour, with init/1 and call/2 functions. ```elixir defmodule JSONHeaderPlug do @behaviour Plug import Plug.Conn def init(opts) do opts end def call(conn, _opts) do put_resp_content_type(conn, "application/json") end end ``` -------------------------------- ### plug macro examples Source: https://plug.hexdocs.pm/Plug.Builder.md Examples of using the plug macro to add a plug module or a plug function with options. ```elixir plug Plug.Logger # plug module plug :foo, some_options: true # plug function ``` -------------------------------- ### configure_session/2 example Source: https://plug.hexdocs.pm/Plug.Conn.md Example usage of configure_session/2 with the :renew option set to true. ```elixir configure_session(conn, renew: true) ``` -------------------------------- ### put_req_header example Source: https://plug.hexdocs.pm/Plug.Conn.md Example call to put_req_header adding an accept header. ```elixir Plug.Conn.put_req_header(conn, "accept", "application/json") ``` -------------------------------- ### assign/3 spec and example Source: https://plug.hexdocs.pm/Plug.Conn.md Specifies the assign/3 function and shows an example of assigning a value to a key in the connection's assigns map. The example demonstrates that assigns are initially nil and can be set and retrieved. ```elixir @spec assign(t(), atom(), term()) :: t() ``` ```elixir iex> conn.assigns[:hello] nil iex> conn = assign(conn, :hello, :world) iex> conn.assigns[:hello] :world ``` -------------------------------- ### decode_done/2 example Source: https://plug.hexdocs.pm/Plug.Conn.Query.md Example showing how to use decode_init/0, decode_each/2, and decode_done/2 together. The decoder is initialized, a key-value pair is added, and then decode_done is called with an initial map containing "initial" => true. The result is a map with both the decoded pair and the initial entries. ```elixir iex> decoder = Plug.Conn.Query.decode_init() iex> decoder = Plug.Conn.Query.decode_each({"foo", "bar"}, decoder) iex> Plug.Conn.Query.decode_done(decoder, %{"initial" => true}) %{"foo" => "bar", "initial" => true} ``` -------------------------------- ### send_resp/1 example with pipeline Source: https://plug.hexdocs.pm/Plug.Conn.md Example showing how to send a 404 response using resp/3 and send_resp/1 in a pipeline. Note that send_resp does not halt the connection, so use halt/1 if needed. ```elixir conn |> Plug.Conn.resp(404, "Not found") |> Plug.Conn.send_resp() ``` -------------------------------- ### run spec and example Source: https://plug.hexdocs.pm/Plug.md Specification for the run/3 function and an example invocation that runs a module plug and an anonymous function. ```elixir @spec run( Plug.Conn.t(), [{module(), opts()} | (Plug.Conn.t() -> Plug.Conn.t())], Keyword.t() ) :: Plug.Conn.t() ``` ```elixir Plug.run(conn, [{Plug.Head, []}, &IO.inspect/1]) ``` -------------------------------- ### decode_each/2 example Source: https://plug.hexdocs.pm/Plug.Conn.Query.md Example showing how to use decode_init/0, decode_each/2, and decode_done/2 together. Two key-value pairs are added to the decoder, then decode_done is called without an initial map. The result is a map with both decoded pairs. ```elixir iex> decoder = Plug.Conn.Query.decode_init() iex> decoder = Plug.Conn.Query.decode_each({"foo", "bar"}, decoder) iex> decoder = Plug.Conn.Query.decode_each({"baz", "bat"}, decoder) iex> Plug.Conn.Query.decode_done(decoder) %{"baz" => "bat", "foo" => "bar"} ``` -------------------------------- ### prepend_resp_headers example Source: https://plug.hexdocs.pm/Plug.Conn.md Example usage of prepend_resp_headers, prepending a content-type header to the connection. ```elixir Plug.Conn.prepend_resp_headers(conn, [{"content-type", "application/json"}]) ``` -------------------------------- ### put_status/2 examples Source: https://plug.hexdocs.pm/Plug.Conn.md Example calls to put_status/2 using an atom and an integer status code. ```elixir Plug.Conn.put_status(conn, :not_found) Plug.Conn.put_status(conn, 200) ``` -------------------------------- ### decode_init/0 Source: https://plug.hexdocs.pm/Plug.Conn.Query.md Starts a stateful decoder. Use decode_each/2 and decode_done/2 to decode and complete. ```APIDOC ## decode_init/0 ### Description Starts a stateful decoder. Use `decode_each/2` and `decode_done/2` to decode and complete. ### Function Signature ```elixir @spec decode_init() :: decoder() ``` ### Usage See `decode_each/2` for examples. ``` -------------------------------- ### get "/hello" Source: https://plug.hexdocs.pm/Plug.Router.md Defines a GET route that matches the path "/hello" and sends a response with status 200 and body "world". ```APIDOC ## GET /hello ### Description Defines a GET route that matches the path "/hello" and sends a response with status 200 and body "world". ### Method GET ### Endpoint /hello ### Response #### Success Response (200) - **body** (string) - The response body "world". #### Response Example "world" ``` -------------------------------- ### send_resp/3 example Source: https://plug.hexdocs.pm/Plug.Conn.md Example call to send_resp/3 that sends a 404 response with body 'Not found'. ```elixir Plug.Conn.send_resp(conn, 404, "Not found") ``` -------------------------------- ### Function plug example: json_header_plug Source: https://plug.hexdocs.pm/Plug.md Example of a function plug that sets the response content type to application/json. ```elixir def json_header_plug(conn, _opts) do Plug.Conn.put_resp_content_type(conn, "application/json") end ``` -------------------------------- ### put_private example Source: https://plug.hexdocs.pm/Plug.Conn.md Shows storing and retrieving a private key with the recommended prefix. ```elixir iex> conn.private[:my_plug_hello] nil iex> conn = put_private(conn, :my_plug_hello, :world) iex> conn.private[:my_plug_hello] :world ``` -------------------------------- ### get "/hello/\:greet" Source: https://plug.hexdocs.pm/Plug.Router.md Defines a GET route that matches the literal path "/hello/:greet" by escaping the colon. ```APIDOC ## GET /hello/\:greet ### Description Defines a GET route that matches the literal path "/hello/:greet" by escaping the colon. ### Method GET ### Endpoint /hello/\:greet ### Response #### Success Response (200) - **body** (string) - The response body "hello". #### Response Example "hello" ``` -------------------------------- ### Manual TLS configuration with custom :ssl options Source: https://plug.hexdocs.pm/https.md Example of configuring an HTTPS server with custom TLS options, including protocol versions, cipher suites, and SNI. Use this when predefined profiles do not meet your needs. The example sets versions to TLS 1.3 and 1.2, specifies modern AEAD ciphers, enables honor_cipher_order, and provides an SNI function. ```elixir Plug.Cowboy.https MyApp.MyPlug, [], port: 8443, certfile: "/etc/letsencrypt/live/example.net/cert.pem", keyfile: "/etc/letsencrypt/live/example.net/privkey.pem", cacertfile: "/etc/letsencrypt/live/example.net/chain.pem", versions: [:"tlsv1.3", :"tlsv1.2"], ciphers: [ # TLS 1.3 Ciphersuites ~c"TLS_AES_256_GCM_SHA384", ~c"TLS_CHACHA20_POLY1305_SHA256", ~c"TLS_AES_128_GCM_SHA256", # Modern TLS 1.2 Ciphersuites ~c"ECDHE-ECDSA-AES128-GCM-SHA256", ~c"ECDHE-RSA-AES128-GCM-SHA256" ], honor_cipher_order: true, sni_fun: &MyPlug.ssl_opts_for_hostname/1 ``` -------------------------------- ### media_type/1 examples Source: https://plug.hexdocs.pm/Plug.Conn.Utils.md Doctests for media_type/1 showing parsing of media types with wildcards, case insensitivity, and parameter handling. ```elixir iex> media_type "text/plain" {:ok, "text", "plain", %{}} iex> media_type "APPLICATION/vnd.ms-data+XML" {:ok, "application", "vnd.ms-data+xml", %{}} iex> media_type "application/media_control+xml" {:ok, "application", "media_control+xml", %{}} iex> media_type "text/*; q=1.0" {:ok, "text", "*", %{"q" => "1.0"}} iex> media_type "*/*; q=1.0" {:ok, "*", "*", %{"q" => "1.0"}} iex> media_type "x y" :error iex> media_type "*/html" :error iex> media_type "/" :error iex> media_type "x/y z" :error ``` -------------------------------- ### merge_req_headers example Source: https://plug.hexdocs.pm/Plug.Conn.md Example call to merge_req_headers with a list of headers. Note: header keys should be lowercase to avoid duplicate keys and HTTP/2 issues; mixed-case headers raise Plug.Conn.InvalidHeaderError with the test adapter. ```elixir Plug.Conn.merge_req_headers(conn, [{"accept", "text/plain"}, {"X-1337", "5P34K"}]) ``` -------------------------------- ### PLUG_EDITOR for TextMate Source: https://plug.hexdocs.pm/Plug.Debugger.md Example of setting PLUG_EDITOR to generate editor links with __FILE__ and __LINE__ placeholders for TextMate. ```text txmt://open/?url=file://__FILE__&line=__LINE__ ``` -------------------------------- ### PLUG_EDITOR with __RELATIVEFILE__ for Docker Source: https://plug.hexdocs.pm/Plug.Debugger.md Example of using __RELATIVEFILE__ in PLUG_EDITOR for projects with different paths, useful in Docker containers. ```text vscode://file//path/to/your/project/__RELATIVEFILE__:__LINE__ ``` -------------------------------- ### get Source: https://plug.hexdocs.pm/Plug.Router.md Dispatches to the path only if the request is a GET request. See match/3 for more examples. ```APIDOC ## `get` ### Description Dispatches to the path only if the request is a GET request. See `match/3` for more examples. ### Method GET ### Endpoint [path] ### Parameters #### Path Parameters - **path** (string) - Required - The path to match. ### Request Example No request body. ### Response No response body specified. ``` -------------------------------- ### get "/hello/*_rest" Source: https://plug.hexdocs.pm/Plug.Router.md Defines a GET route with a glob pattern that matches all routes starting with /hello, discarding the rest of the path. ```APIDOC ## GET /hello/*_rest ### Description Defines a GET route with a glob pattern that matches all routes starting with /hello, discarding the rest of the path. ### Method GET ### Endpoint /hello/*_rest ### Response #### Success Response (200) - **body** (string) - The response body "matches all routes starting with /hello". #### Response Example "matches all routes starting with /hello" ``` -------------------------------- ### init/1 Source: https://plug.hexdocs.pm/Plug.Session.Store.md Callback to initialize the store. ```APIDOC ## `init/1` ### Description Initializes the store. The options returned from this function will be given to `get/3`, `put/4`, and `delete/3`. ### Callback ```elixir @callback init(opts :: Plug.opts()) :: Plug.opts() ``` ### Parameters - **opts** (`Plug.opts()`) - The initial options. ### Returns - `Plug.opts()` - The processed options. ``` -------------------------------- ### Halting a plug pipeline with Plug.Conn.halt/1 Source: https://plug.hexdocs.pm/Plug.Builder.md Demonstrates halting a pipeline so downstream plugs are not invoked. In this example, Plug.Logger never gets called. ```elixir defmodule PlugUsingHalt do use Plug.Builder plug :stopper plug Plug.Logger def stopper(conn, _opts) do halt(conn) end end ``` -------------------------------- ### Hello world module plug with Cowboy Source: https://plug.hexdocs.pm/ A minimal hello world example using the Cowboy webserver. Save to a file and run with `elixir hello_world.exs`, then access http://localhost:4000/. ```elixir Mix.install([:plug, :plug_cowboy]) defmodule MyPlug do import Plug.Conn def init(options) do # initialize options options end def call(conn, _opts) do conn |> put_resp_content_type("text/plain") |> send_resp(200, "Hello world") end end require Logger webserver = {Plug.Cowboy, plug: MyPlug, scheme: :http, options: [port: 4000]} {:ok, _} = Supervisor.start_link([webserver], strategy: :one_for_one) Logger.info("Plug now running on localhost:4000") Process.sleep(:infinity) ``` -------------------------------- ### Configure Plug.Cowboy HTTPS with encrypted private key Source: https://plug.hexdocs.pm/https.md Use this Elixir configuration to start an HTTPS server with Plug.Cowboy, specifying an encrypted private key file and its password. The :password option is required for encrypted PEM keys. The example uses port 8443 and Let's Encrypt certificate files. ```elixir Plug.Cowboy.https MyApp.MyPlug, [], port: 8443, certfile: "/etc/letsencrypt/live/example.net/cert.pem", keyfile: "/etc/letsencrypt/live/example.net/privkey_aes.pem", cacertfile: "/etc/letsencrypt/live/example.net/chain.pem", password: "SECRET" ``` -------------------------------- ### chunk/2 spec and example Source: https://plug.hexdocs.pm/Plug.Conn.md Specifies the chunk/2 function and shows an example of streaming chunks using Enum.reduce_while/3. The example halts if the chunk fails with :closed. ```elixir @spec chunk(t(), body()) :: {:ok, t()} | {:error, term()} | no_return() ``` ```elixir Enum.reduce_while(~w(each chunk as a word), conn, fn (chunk, conn) -> case Plug.Conn.chunk(conn, chunk) do {:ok, conn} -> {:cont, conn} {:error, :closed} -> {:halt, conn} end end) ``` -------------------------------- ### Callback: init/1 Source: https://plug.hexdocs.pm/Plug.Session.Store.md Initializes the store. The options returned from this function will be given to get/3, put/4, and delete/3. ```elixir @callback init(opts :: Plug.opts()) :: Plug.opts() ``` -------------------------------- ### put_resp_header/3 example Source: https://plug.hexdocs.pm/Plug.Conn.md Example call to put_resp_header/3 that sets the content-type header to application/json. ```elixir Plug.Conn.put_resp_header(conn, "content-type", "application/json") ``` -------------------------------- ### Create a new Elixir project with --sup flag Source: https://plug.hexdocs.pm/ Command to start a new Elixir project with a supervision tree, which is the first step in setting up a supervised Plug handler. ```shell $ mix new my_app --sup ``` -------------------------------- ### merge_resp_headers example Source: https://plug.hexdocs.pm/Plug.Conn.md Example usage of merge_resp_headers, merging a list of headers into the connection. ```elixir Plug.Conn.merge_resp_headers(conn, [{"content-type", "text/plain"}, {"X-1337", "5P34K"}]) ``` -------------------------------- ### delete_resp_header/2 example Source: https://plug.hexdocs.pm/Plug.Conn.md Example usage of delete_resp_header/2 to delete the content-type response header. ```elixir Plug.Conn.delete_resp_header(conn, "content-type") ``` -------------------------------- ### Invoke the router as a plug Source: https://plug.hexdocs.pm/Plug.Router.md Shows how to call the router as a plug with the init options. ```elixir AppRouter.call(conn, AppRouter.init([])) ``` -------------------------------- ### delete_req_header/2 example Source: https://plug.hexdocs.pm/Plug.Conn.md Example usage of delete_req_header/2 to delete the content-type request header. ```elixir Plug.Conn.delete_req_header(conn, "content-type") ``` -------------------------------- ### Building a plug pipeline with Plug.Builder Source: https://plug.hexdocs.pm/Plug.Builder.md Shows how to define a module using Plug.Builder, add module and function plugs, and implement a function plug. The pipeline executes plugs from top to bottom. ```elixir defmodule MyApp do use Plug.Builder plug Plug.Logger plug :hello, upper: true # A function from another module can be plugged too, provided it's # imported into the current module first. import AnotherModule, only: [interesting_plug: 2] plug :interesting_plug def hello(conn, opts) do body = if opts[:upper], do: "WORLD", else: "world" send_resp(conn, 200, body) end end ``` -------------------------------- ### init/1 Source: https://plug.hexdocs.pm/Plug.md Callback that must be implemented by module plugs. It takes a set of options and initializes them, returning the initialized options. ```APIDOC ## init/1 ### Description Callback that must be implemented by module plugs. It takes a set of options and initializes them, returning the initialized options. ### Callback Signature ```elixir @callback init(opts()) :: opts() ``` ### Parameters - **opts** (opts()) - Required - The options to initialize. ### Returns - **opts()** - The initialized options. ``` -------------------------------- ### Test a plug with Plug.Test Source: https://plug.hexdocs.pm/ Use ExUnit and Plug.Test to test a plug. Create a test connection with conn(:get, "/hello"), invoke the plug with MyRouter.call(conn, @opts), and assert the response state, status, and body. ```elixir defmodule MyPlugTest do use ExUnit.Case, async: true import Plug.Test import Plug.Conn @opts MyRouter.init([]) test "returns hello world" do # Create a test connection conn = conn(:get, "/hello") # Invoke the plug conn = MyRouter.call(conn, @opts) # Assert the response and status assert conn.state == :sent assert conn.status == 200 assert conn.resp_body == "world" end end ``` -------------------------------- ### prepend_req_headers example Source: https://plug.hexdocs.pm/Plug.Conn.md Example usage of prepend_req_headers, prepending a header to the connection request headers. ```elixir Plug.Conn.prepend_req_headers(conn, [{"accept", "application/json"}]) ``` -------------------------------- ### Configure Plug.Session with cookie store Source: https://plug.hexdocs.pm/Plug.Session.COOKIE.md Shows how to configure the Plug.Session plug to use the :cookie store, specifying the session key, encryption salt, signing salt, and log level. This is the typical setup for using Plug.Session.COOKIE. ```elixir plug Plug.Session, store: :cookie, key: "_my_app_session", encryption_salt: "cookie store encryption salt", signing_salt: "cookie store signing salt", log: :debug ``` -------------------------------- ### update_resp_header example Source: https://plug.hexdocs.pm/Plug.Conn.md Example call to update_resp_header that updates the 'content-type' header with a function appending charset. ```elixir Plug.Conn.update_resp_header( conn, "content-type", "application/json; charset=utf-8", &(&1 <> "; charset=utf-8") ) ``` -------------------------------- ### update_req_header example Source: https://plug.hexdocs.pm/Plug.Conn.md Example call to update_req_header that updates the 'accept' header with a function appending charset. ```elixir Plug.Conn.update_req_header( conn, "accept", "application/json; charset=utf-8", &(&1 <> "; charset=utf-8") ) ``` -------------------------------- ### Example implementation of Plug.Exception for actions Source: https://plug.hexdocs.pm/Plug.Exception.md Shows how to implement the actions callback for a custom exception to return an action with a label and handler. ```elixir defimpl Plug.Exception, for: ActionableExample do def actions(_), do: [%{label: "Print HI", handler: {IO, :puts, ["Hi!"]}}] end ``` -------------------------------- ### put_resp_content_type example Source: https://plug.hexdocs.pm/Plug.Conn.md Example usage of put_resp_content_type with 'application/json', resulting in the content-type header including 'charset=utf-8'. ```elixir iex> conn = put_resp_content_type(conn, "application/json") iex> get_resp_header(conn, "content-type") ["application/json; charset=utf-8"] ``` -------------------------------- ### Configure HTTPS listener with combined certificate file Source: https://plug.hexdocs.pm/https.md Shows the certfile and keyfile options when the certificate file contains both the server certificate and all necessary CA chain certificates, so cacertfile is not needed. ```elixir #... certfile: "/etc/letsencrypt/live/example.net/fullchain.pem", keyfile: "/etc/letsencrypt/live/example.net/privkey.pem" ``` -------------------------------- ### merge_private example Source: https://plug.hexdocs.pm/Plug.Conn.md Example showing merge_private assigns a private key, replacing nil with :world. ```elixir iex> conn.private[:my_plug_hello] nil iex> conn = merge_private(conn, my_plug_hello: :world) iex> conn.private[:my_plug_hello] :world ``` -------------------------------- ### merge_assigns example Source: https://plug.hexdocs.pm/Plug.Conn.md Example showing merge_assigns assigns a value to a key, replacing nil with :world. ```elixir iex> conn.assigns[:hello] nil iex> conn = merge_assigns(conn, hello: :world) iex> conn.assigns[:hello] :world ``` -------------------------------- ### init/1 function Source: https://plug.hexdocs.pm/Plug.Builder.md The `init/1` function is defined by `Plug.Builder` and returns the options it receives. It can be overridden to customize behavior. ```APIDOC ## init/1 function ### Description The `init/1` function is defined by `Plug.Builder` and returns the options it receives. It can be overridden to customize behavior. ### Usage ```elixir def init(opts) do opts end ``` ### Parameters - **opts** (term) - Required - The options passed to the plug. ### Returns - The options (term). ``` -------------------------------- ### params/1 examples Source: https://plug.hexdocs.pm/Plug.Conn.Utils.md Doctests for params/1 showing parsing of header parameters, case insensitivity, quoting, and discarding invalid pairs. ```elixir iex> params("foo=bar") %{"foo" => "bar"} iex> params(" foo=bar ") %{"foo" => "bar"} iex> params("FOO=bar") %{"foo" => "bar"} iex> params("Foo=bar; baz=BOING") %{"foo" => "bar", "baz" => "BOING"} iex> params("foo=BAR ; wat") %{"foo" => "BAR"} iex> params("foo=\"bar\"; baz=\"boing\"") %{"foo" => "bar", "baz" => "boing"} iex> params("foo=\"bar;\"; baz=\"boing\"") %{"foo" => "bar;", "baz" => "boing"} iex> params("=") %{} iex> params(";") %{} iex> params("foo=") %{} ``` -------------------------------- ### Define a GET route with a static path Source: https://plug.hexdocs.pm/Plug.Router.md A route that matches only GET requests to "/hello". ```elixir get "/hello" do send_resp(conn, 200, "world") end ``` -------------------------------- ### Compile-time usage: plug :basic_auth with inline credentials Source: https://plug.hexdocs.pm/Plug.BasicAuth.md Sets up Basic HTTP authentication with a single username and password at compile time. The request is denied with 401 and halted on first access, prompting the browser for credentials. ```elixir import Plug.BasicAuth plug :basic_auth, username: "hello", password: "secret" ``` -------------------------------- ### Configure HTTPS listener with bundled certificate files Source: https://plug.hexdocs.pm/https.md Configures an HTTPS listener using certificate files stored in the application's priv directory. Requires setting otp_app to the OTP application name so relative paths resolve correctly. Remember to exclude the PEM files from version control. ```elixir Plug.Cowboy.https MyApp.MyPlug, [], port: 8443, cipher_suite: :strong, certfile: "priv/cert/selfsigned.pem", keyfile: "priv/cert/selfsigned_key.pem", otp_app: :my_app ``` -------------------------------- ### get_http_protocol spec and example Source: https://plug.hexdocs.pm/Plug.Conn.md Spec for get_http_protocol/1, which returns the HTTP protocol and version. The example shows the return value for a typical connection. ```elixir @spec get_http_protocol(t()) :: Plug.Conn.Adapter.http_protocol() ``` ```elixir iex> get_http_protocol(conn) :"HTTP/1.1" ``` -------------------------------- ### Define a basic Plug.Router with routes and catch-all Source: https://plug.hexdocs.pm/ Defines a router module using Plug.Router. It includes the :match and :dispatch plugs, a GET route for /hello, a forward to UsersRouter, and a catch-all match that returns 404. The router is a plug and contains its own plug pipeline. ```elixir defmodule MyRouter do use Plug.Router plug :match plug :dispatch get "/hello" do send_resp(conn, 200, "world") end forward "/users", to: UsersRouter match _ do send_resp(conn, 404, "oops") end end ```