Plug.Conn

Parsed documentation:
View on GitHub
The Plug connection.

This module defines a `Plug.Conn` struct and the main functions
for working with Plug connections.

Note request headers are normalized to lowercase and response
headers are expected to have lower-case keys.

## Request fields

These fields contain request information:

  * `host` - the requested host as a binary, example: `"www.example.com"`
  * `method` - the request method as a binary, example: `"GET"`
  * `path_info` - the path split into segments, example: `["hello", "world"]`
  * `script_name` - the initial portion of the URL's path that corresponds to the application
    routing, as segments, example: ["sub","app"].
  * `request_path` - the requested path, example: `/trailing/and//double//slashes/`
  * `port` - the requested port as an integer, example: `80`
  * `peer` - the actual TCP peer that connected, example: `{{127, 0, 0, 1}, 12345}`. Often this
    is not the actual IP and port of the client, but rather of a load-balancer or request-router.
  * `remote_ip` - the IP of the client, example: `{151, 236, 219, 228}`. This field is meant to
    be overwritten by plugs that understand e.g. the `X-Forwarded-For` header or HAProxy's PROXY
    protocol. It defaults to peer's IP.
  * `req_headers` - the request headers as a list, example: `[{"content-type", "text/plain"}]`.
    Note all headers will be downcased.
  * `scheme` - the request scheme as an atom, example: `:http`
  * `query_string` - the request query string as a binary, example: `"foo=bar"`

## Fetchable fields

The request information in these fields is not populated until it is fetched
using the associated `fetch_` function. For example, the `cookies` field uses
`fetch_cookies/2`.

If you access these fields before fetching them, they will be returned as
`Plug.Conn.Unfetched` structs.

  * `cookies`- the request cookies with the response cookies
  * `body_params` - the request body params, populated through a `Plug.Parsers` parser.
  * `query_params` - the request query params, populated through `fetch_query_params/2`
  * `path_params` - the request path params, populated by routers such as `Plug.Router`
  * `params` - the request params, the result of merging the `:body_params` and `:query_params`
     with `:path_params`
  * `req_cookies` - the request cookies (without the response ones)

## Response fields

These fields contain response information:

  * `resp_body` - the response body, by default is an empty string. It is set
    to nil after the response is set, except for test connections.
  * `resp_charset` - the response charset, defaults to "utf-8"
  * `resp_cookies` - the response cookies with their name and options
  * `resp_headers` - the response headers as a list of tuples, by default `cache-control`
    is set to `"max-age=0, private, must-revalidate"`. Note, response headers
    are expected to have lower-case keys.
  * `status` - the response status

Furthermore, the `before_send` field stores callbacks that are invoked
before the connection is sent. Callbacks are invoked in the reverse order
they are registered (callbacks registered first are invoked last) in order
to reproduce a pipeline ordering.

## Connection fields

  * `assigns` - shared user data as a map
  * `owner` - the Elixir process that owns the connection
  * `halted` - the boolean status on whether the pipeline was halted
  * `secret_key_base` - a secret key used to verify and encrypt cookies.
    the field must be set manually whenever one of those features are used.
    This data must be kept in the connection and never used directly, always
    use `Plug.Crypto.KeyGenerator.generate/3` to derive keys from it
  * `state` - the connection state

The connection state is used to track the connection lifecycle. It starts
as `:unset` but is changed to `:set` (via `Plug.Conn.resp/3`) or `:file`
(when invoked via `Plug.Conn.send_file/3`). Its final result is
`:sent` or `:chunked` depending on the response model.

## Private fields

These fields are reserved for libraries/framework usage.

  * `adapter` - holds the adapter information in a tuple
  * `private` - shared library data as a map

## Protocols

`Plug.Conn` implements both the Collectable and Inspect protocols
out of the box. The inspect protocol provides a nice representation
of the connection while the collectable protocol allows developers
to easily chunk data. For example:

    # Send the chunked response headers
    conn = send_chunked(conn, 200)

    # Pipe the given list into a connection
    # Each item is emitted as a chunk
    Enum.into(~w(each chunk as a word), conn)

## Custom status codes

Plug allows status codes to be overridden or added in order to allow new codes
not directly specified by Plug or its adapters. Adding or overriding a status
code is done through the Mix configuration of the `:plug` application. For
example, to override the existing 404 reason phrase for the 404 status code
("Not Found" by default) and add a new 451 status code, the following config
can be specified:

    config :plug, :statuses, %{
      404 => "Actually This Was Found",
      451 => "Unavailable For Legal Reasons"
    }

As this configuration is Plug specific, Plug will need to be recompiled for
the changes to take place: this will not happen automatically as dependencies
are not automatically recompiled when their configuration changes. To recompile
Plug:

    mix deps.clean --build plug

The atoms that can be used in place of the status code in many functions are
inflected from the reason phrase of the status code. With the above
configuration, the following will all work:

    put_status(conn, :not_found)                     # 404
    put_status(conn, :actually_this_was_found)       # 404
    put_status(conn, :unavailable_for_legal_reasons) # 451

Even though 404 has been overridden, the `:not_found` atom can still be used
to set the status to 404 as well as the new atom `:actually_this_was_found`
inflected from the reason phrase "Actually This Was Found".
No suggestions.
Please help! Open an issue on GitHub if this assessment is incorrect.