Cowboy Documentation

repository·master·Indexed 27 days ago

https://github.com/ninenines/cowboy

Cowboy is a lightweight, high-performance HTTP server written in Erlang/OTP, designed to be embedded into other Erlang applications. It supports HTTP/1.1, HTTP/2, and Websockets, providing robust routing capabilities and a flexible request/response flow built on the Ranch network library.

Tokens
59K
Snippets
127
Records
402
Agent score
90%

What's inside Cowboy

  1. Overview of Cowboy HTTP server

    master

    Cowboy is a small, fast, and modern HTTP server for Erlang/OTP. It is designed to provide a complete HTTP stack within a small codebase, optimized for low latency and low memory usage by utilizing binary strings.

    Key features include:

    • Routing: Selectively dispatches requests to Erlang handlers.
    • Embeddability: Uses Ranch for connection management, allowing it to be easily embedded into other Erlang applications.
    • Performance: Optimized for low latency and low memory footprint.
  2. Overview of Cowboy modules and protocols

    master

    Cowboy is an HTTP server for Erlang/OTP supporting HTTP/1.1, HTTP/2, and Websocket protocols. Key components include:

    Core Modules

    • cowboy: Listener management
    • cowboy_req: Request and response handling
    • cowboy_router: Routing logic
    • cowboy_constraints: Routing constraints

    Protocols

    • cowboy_http: HTTP/1.1
    • cowboy_http2: HTTP/2
    • cowboy_websocket: Websocket

    Handlers and Behaviors

    • cowboy_static: Static file handler
    • cowboy_handler: Plain HTTP handlers
    • cowboy_loop: Loop handlers
    • cowboy_middleware: Middlewares
    • cowboy_rest: REST handlers
    • cowboy_stream: Stream handlers
    • cowboy_websocket: Websocket handlers
  3. Use cowboy_router middleware for request routing

    master

    The cowboy_router middleware maps requested hosts and paths to specific handlers.

    To use it, you must provide dispatch rules in the middleware environment. These rules can be provided directly or as a tuple {persistent_term, Key}, where Cowboy will use persistent_term:get(Key) to retrieve them.

    When a route matches:

    • The handler environment value is set to the handler module.
    • The handler_opts environment value is set to the handler's initial state.

    If no route matches:

    • A 400 response is sent if no host was found.
    • A 404 response is sent if a host was found but the path did not match.
  4. Understand the `cowboy_req` function types

    master

    The cowboy_req module functions are categorized into four types based on their name pattern and return type. This is critical for knowing how to handle the Req object:

    1. Access: Functions starting with parse_* or match_* (and those with no verb). They return a Value.
    2. Question: Functions starting with has_*. They return a boolean().
    3. Modification: Functions starting with set_*. They return a new Req object. You must use the returned Req object in place of the original.
    4. Action: Any other verb. They return ok | {Result, Value, Req}.

    Note: Certain actions (like sending a response or reading a body) can only be performed once. Functions that perform actions write state into the Req object to enforce these constraints.

  5. Understand the Req object

    master

    The Req object is a map used to obtain information about an HTTP request, read its body, or send a response. It is not a traditional object-oriented object but a simple map that can be accessed directly via pattern matching or through the cowboy_req module functions.

    Important Notes:

    • Direct Access: You can access public fields like method, version, scheme, host, port, path, qs, headers, peer, and cert directly from the map.
    • Internal Fields: Do not access fields not explicitly documented, as they may change in future releases without notice.
    • Modifying Req: You can add new fields to the Req map, but you should namespace them to avoid conflicts with future Cowboy updates or third-party projects. When using functions from cowboy_req that return an updated Req (like read, reply, set, and delete), always use the returned Req object.
  6. Understand the Cowboy request/response flow

    master

    Cowboy is an HTTP server (supporting HTTP/1.1, HTTP/2, and Websockets) built on top of the Ranch network library.

    The Request Lifecycle:

    1. Connection: A Ranch acceptor process accepts the new connection.
    2. Stream Creation: Cowboy receives requests and creates a 'stream' (a set of request/response and associated events).
    3. Stream Handling: Cowboy defers stream events to stream handler modules.
    4. Default Handler: By default, Cowboy uses cowboy_stream_h. This handler creates a new process for every request. This process executes middlewares, the router, and finally the handlers.
    5. Response: A response can be sent at almost any point. If an error occurs before a stream is initialized, stream handlers receive a special error event.

    Concurrency Differences:

    • HTTP/1.1: Requests arrive sequentially.
    • HTTP/2: Requests may arrive and be processed concurrently via interleaved frames on a single connection.
  7. Protocol support in Cowboy

    master

    Cowboy is a modern web server that provides transparent support for several key web standards and protocols:

    • HTTP/2: Provides efficient, binary-based communication with support for concurrent requests, header compression, and server push. Cowboy automatically falls back to HTTP/1.1 for clients that do not support HTTP/2.
    • HTTP/1.1: Supports standard methods, headers, and status codes. It is compatible with HTTP/1.0.
    • Websocket: Provides a two-way, asynchronous communication channel built on top of HTTP/1.1. It supports both UTF-8 encoded text and binary data, as well as ping/pong mechanisms for connection health. Cowboy uses Websocket handlers to manage these connections.
    • Long-lived requests: Supports long-polling and streaming (such as Server-Sent Events via text/event-stream) using loop handlers. This works regardless of the underlying protocol (HTTP/1.1 or HTTP/2).
    • REST: Supports the REpresentational State Transfer architectural style via REST handlers, which simplify implementing REST APIs on top of HTTP.
  8. Switch to different handler types (Websocket, REST, Loop)

    master

    You can use the init/2 callback to switch the current request to a different handler type. Instead of returning ok as the first element of the return tuple, return the module name of the desired handler type.

    Cowboy provides built-in handler types:

    • cowboy_rest (REST handlers)
    • cowboy_websocket (Websocket handlers)
    • cowboy_loop (Loop handlers)

    You can also define and switch to your own custom handler types.

    init(Req, State) ->
        {cowboy_websocket, Req, State}.
  9. Check Cowboy 2.0 Compatibility Requirements

    master

    Before using Cowboy 2.0, ensure your environment meets these requirements:

    • Erlang/OTP: Requires version 19.0 or above. (Compatibility with R16, 17, and 18 has been dropped).
    • Cowlib: Requires version 2.0 or above.
    • Ranch: Compatible with 1.0 or above (tested with 1.4+).
    • Supported Platforms: Arch Linux, Ubuntu, FreeBSD, Windows, and OSX.
  10. Configure HTTP/2 protocol options in Cowboy

    master

    The cowboy_http2 module implements HTTP/2 as a Ranch protocol. You can configure HTTP/2 behavior by passing an options map to cowboy:start_clear/3 or cowboy:start_tls/3 when starting listeners.

    These options can be updated dynamically without restarting listeners using ranch:get_protocol_options/1 and ranch:set_protocol_options/2.