gluegun/message

Decoding and awaiting asynchronous Gun stream messages.

Gun sends HTTP, HTTP/2 push, upgrade, and WebSocket events as Erlang messages. This module decodes those messages into Gleam types for callers using lower-level streaming or advanced flows.

Types

A decoded Message paired with the connection and stream Gun says it belongs to.

Gun’s mailbox tuples (gun_response, gun_data, gun_inform, gun_trailers, gun_push, gun_upgrade, gun_ws) always name the connection process and stream reference a message came from. decode preserves both alongside the decoded Message so a process that owns several concurrent streams — for example an HTTP/2 connection with server push, or several requests sharing one reply_to process — can attribute each message to the right stream instead of assuming messages arrive for whichever stream the caller currently has in mind.

stream names the stream that delivered the message; for Push it is the existing stream the server pushed on, not the new stream carried inside message.Push.

pub type Envelope {
  Envelope(
    connection: connection.Connection,
    stream: request.Stream,
    message: Message,
  )
}

Constructors

WebSocket frames delivered inside Gun stream messages.

On the wire Gun delivers close (atom) as Close and {close, Code, Reason} as CloseWithReason.

pub type Frame {
  Text(String)
  Binary(BitArray)
  Ping(BitArray)
  Pong(BitArray)
  Close
  CloseWithReason(code: Int, reason: BitArray)
}

Constructors

  • Text(String)

    A UTF-8 text frame. Gun validates the payload as UTF-8 before delivery.

  • Binary(BitArray)

    A binary frame. The payload is an opaque byte string.

  • Ping(BitArray)

    A ping control frame. Reply with Pong to keep the connection alive.

  • Pong(BitArray)

    A pong control frame. Usually delivered in response to a Ping.

  • Close

    A close control frame with no status code or reason.

  • CloseWithReason(code: Int, reason: BitArray)

    A close control frame carrying a numeric close code and opaque reason payload (RFC 6455 §5.5.1).

A raw Gun stream message, exactly as Gun delivers it to the process that owns the stream.

This external type has no Gleam constructors: values come from Gun itself (or from an Erlang FFI function of your own that receives them). Use decode to turn one into a typed Message.

pub type GunMessage

Gun HTTP stream messages delivered by the Erlang Gun client.

Sequencing for a normal HTTP response: zero or more Inform (1xx) → one Response → zero or more Data (until Fin) → optional Trailers. Push and Upgrade may appear for HTTP/2 server push and protocol switching. WebSocket only appears after a successful upgrade.

This type is closed; new variants are a breaking change. Pin to a major version.

pub type Message {
  Inform(status: Int, headers: List(#(String, String)))
  Response(
    fin: fin.Fin,
    status: Int,
    headers: List(#(String, String)),
  )
  Data(fin: fin.Fin, data: BitArray)
  Trailers(headers: List(#(String, String)))
  Push(
    stream: request.Stream,
    method: http.Method,
    uri: String,
    headers: List(#(String, String)),
  )
  Upgrade(
    protocols: List(String),
    headers: List(#(String, String)),
  )
  WebSocket(frame: Frame)
}

Constructors

  • Inform(status: Int, headers: List(#(String, String)))

    A 1xx informational response. May appear multiple times before the final Response.

  • Response(
      fin: fin.Fin,
      status: Int,
      headers: List(#(String, String)),
    )

    The final HTTP response headers. fin is Fin when there is no body.

  • Data(fin: fin.Fin, data: BitArray)

    A response body chunk. fin is Fin on the last chunk.

  • Trailers(headers: List(#(String, String)))

    Trailing headers delivered after the body (HTTP/1.1 trailers or HTTP/2 trailer frames).

  • Push(
      stream: request.Stream,
      method: http.Method,
      uri: String,
      headers: List(#(String, String)),
    )

    An HTTP/2 server push. The stream is a new stream the caller may await or cancel.

  • Upgrade(
      protocols: List(String),
      headers: List(#(String, String)),
    )

    A successful protocol upgrade. Subsequent messages on this stream use the new protocol (e.g. WebSocket).

  • WebSocket(frame: Frame)

    A decoded WebSocket frame. Only delivered after an upgrade.

Values

pub fn await(
  connection: connection.Connection,
  stream: request.Stream,
  timeout: connection.Timeout,
) -> Result(Message, error.GluegunError)

Await the next Gun message for a stream.

Blocks the calling process until a message arrives, the stream errors, or timeout elapses. Messages arrive in the order described on Message: Inform* → Response → Data* → Trailers?. Use this for streaming responses, server push, or any flow where you need messages as they arrive.

Errors: Timeout, ConnectionDown, ConnectionError, StreamError, InvalidMessage, ErlangError.

pub fn await_body(
  connection: connection.Connection,
  stream: request.Stream,
  timeout: connection.Timeout,
) -> Result(BitArray, error.GluegunError)

Await and collect the full response body for a stream.

Drains body chunks until the final Fin and returns the concatenated payload. Headers must already have been consumed (e.g. via a prior await that returned Response). When the response ends with trailers, the collected body is returned and the trailer headers are dropped; use await if you need them. For incremental access use await directly. The full body is held in memory; use the lower-level loop for very large responses.

Errors: Timeout, ConnectionDown, ConnectionError, StreamError, ErlangError.

pub fn decode(
  message: GunMessage,
) -> Result(Envelope, error.GluegunError)

Decode a raw Erlang Gun mailbox message into a typed Message, paired with the connection and stream it belongs to.

Useful when receiving Gun messages outside Gluegun’s helpers (for example inside a custom receive loop that hands the message to Gluegun through your own Erlang FFI). Accepts the mailbox tuples Gun sends to the stream owner (gun_response, gun_data, gun_inform, gun_trailers, gun_push, gun_upgrade, gun_ws). For gun_error, returns StreamError or ConnectionError according to the message’s scope. For gun_down, returns ConnectionDown with Gun’s reason. Error results do not include an envelope. Returns DecodeError for an unrecognized or malformed message, including the shorter terms returned by gun:await/3.

✨ Search Document