Skip to main content

src/starfruit.gleam

import gleam/erlang/process
import gleam/int
import gleam/io
import gleam/option.{None}
import gleam/string
import gleam/time/calendar
import gleam/time/timestamp
import glisten.{Packet}
import glisten/transport
import starfruit/internal

/// This is all you need! 

pub fn start(
  port port: Int,
  cert cert: String,
  key key: String,
  loopback loopback: Bool,
  hostname hostname: String,
) -> Nil {
  io.print(
    string.concat([
      "⋆✴︎˚。⋆ Starfruit is listening on port ",
      int.to_string(port),
      "!! ⋆。˚✴︎⋆\n",
    ]),
  )
  let assert Ok(_) =
    glisten.new(fn(_conn) { #(Nil, None) }, fn(_state, msg, conn) {
      let assert Ok(source) = glisten.get_connection_info(conn)
      io.print(
        timestamp.to_rfc3339(timestamp.system_time(), calendar.local_offset())
        <> "\nIncoming request from "
        <> glisten.ip_address_to_string(source.ip_address)
        <> " for ",
      )
      // unsure if this case is necessary, i think glisten will deny

      // it automatically?

      case conn.transport {
        transport.Tcp -> {
          glisten.stop()
        }
        transport.Ssl -> {
          let assert Packet(msg) = msg
          let _resp =
            internal.parse_url(msg, port, hostname, source.ip_address)
            |> internal.router()
            |> internal.response()
            |> internal.senddata(conn)
          glisten.stop()
        }
      }
    })
    |> glisten.with_tls(certfile: cert, keyfile: key)
    |> internal.bind(loopback)
    |> glisten.start(port)

  process.sleep_forever()
}