mist

repository·master·Indexed 19 days ago

https://github.com/rawhat/mist

A high-performance web server written in Gleam. It provides modern web capabilities including WebSockets, chunked encoding, and streaming request/response handling. Features include a Builder pattern for server configuration, static file serving via mist.send_file, and support for both reading and streaming request bodies.

Tokens
1.8K
Snippets
11
Records
15
Agent score
68%

What's inside mist

  1. How to start a mist server

    master

    A mist server is initialized using a Builder pattern. You start with mist.new, configure it using various methods like bind, port, and with_ipv6, and finally call mist.start with a handler function. The handler function receives a Request(Connection) and must return a Response(ResponseData).

    import mist
    import gleam/http/request.{type Request}
    import gleam/http/response.{type Response}
    import mist.{type Connection, type ResponseData}
    
    pub fn main() {
      let assert Ok(_) =
        fn(req: Request(Connection)) -> Response(ResponseData) {
          // Your routing logic here
          response.new(200) |> response.set_body(mist.Bytes(bytes_tree.new()))
        }
        |> mist.new()
        |> mist.bind("localhost")
        |> mist.port(4000)
        |> mist.start()
    
      // Keep the process alive
      process.sleep_forever()
    }
  2. Run and test the complete example project

    master

    If you are working within the complete example directory, you can use the following Gleam commands to manage development:

    • gleam run: Executes the project.
    • gleam test: Runs the project's test suite.
    • gleam shell: Opens an Erlang shell for interactive development.
    gleam run   # Run the project
    gleam test  # Run the tests
    gleam shell # Run an Erlang shell
  3. Develop and run the eventz example project

    master

    If you are working directly within the eventz example repository, you can use the following Gleam commands to manage development:

    • gleam run: Executes the project.
    • gleam test: Runs the test suite.
    • gleam shell: Opens an Erlang shell for interactive development.
    gleam run   # Run the project
    gleam test  # Run the tests
    gleam shell # Run an Erlang shell
  4. Install mist and its dependencies

    master

    To use mist in a new Gleam project, create a new project and add the necessary dependencies using gleam add. You will typically need mist, logging, gleam_erlang, and gleam_http for a complete web server setup.

    $ gleam new <your_project>
    $ cd <your_project>
    $ gleam add mist logging gleam_erlang gleam_http
  5. Read request bodies with mist.read_body

    master
    To read the entire body of an HTTP request into memory, use mist.read_body(request, max_size). This is useful for standard POST/PUT requests where the payload size is known or bounded.
  6. Serve files with mist.send_file

    master

    mist.send_file provides an easy way to serve static files. It returns a Result containing the file data (as a Response body) or an error. You can specify an offset and a limit for partial file serving.

    // Example file serving
    mist.send_file(file_path, offset: 0, limit: None)
      |> result.map(fn(file) {
        response.new(200)
        |> response.set_body(file)
      })
  7. Stream request bodies with mist.stream

    master

    For large request bodies, use mist.stream(req) to get a consume function. This function allows you to pull chunks of data from the request incrementally, preventing high memory usage.

    case mist.stream(req) {
      Ok(consume) -> {
        // consume(size) returns Result(mist.Chunk, mist.ReadError)
        // mist.Chunk(data, next_consume_fn)
      }
      Error(_reason) -> { /* handle error */ }
    }
  8. Handle chunked responses with mist.chunked

    master

    Use mist.chunked to stream a response to the client in chunks. This function takes the request, a base response, an initialization function that spawns the chunk producer, and a handler that manages the chunking lifecycle.

    Inside the handler, use mist.send_chunk(connection, bit_array) to send data and mist.chunk_continue(state) to proceed. Use mist.chunk_stop() to finish the response.