From abc4526f84b45c1994edea67804295568cc80665 Mon Sep 17 00:00:00 2001 From: Justin Blake Date: Sun, 24 Dec 2023 14:54:41 -0500 Subject: [PATCH] Add basic HTTP server example --- http-server/README.md | 7 +++ http-server/gren.json | 16 +++++++ http-server/src/Main.gren | 90 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 http-server/README.md create mode 100644 http-server/gren.json create mode 100644 http-server/src/Main.gren diff --git a/http-server/README.md b/http-server/README.md new file mode 100644 index 0000000..9916cf4 --- /dev/null +++ b/http-server/README.md @@ -0,0 +1,7 @@ +# Basic HTTP Server Example + +``` +gren make src/Main.gren && node app +``` + +Starts server on diff --git a/http-server/gren.json b/http-server/gren.json new file mode 100644 index 0000000..af5f15b --- /dev/null +++ b/http-server/gren.json @@ -0,0 +1,16 @@ +{ + "type": "application", + "platform": "node", + "source-directories": [ + "src" + ], + "gren-version": "0.3.0", + "dependencies": { + "direct": { + "gren-lang/core": "4.0.1", + "gren-lang/node": "3.0.1", + "gren-lang/url": "3.0.0" + }, + "indirect": {} + } +} diff --git a/http-server/src/Main.gren b/http-server/src/Main.gren new file mode 100644 index 0000000..066a3c2 --- /dev/null +++ b/http-server/src/Main.gren @@ -0,0 +1,90 @@ +module Main exposing (main) + +import Node +import Stream exposing (Stream) +import Node exposing (Environment, Program) +import HttpServer as Http exposing (ServerError(..)) +import HttpServer.Response as Response exposing (Response) +import Init +import Task +import Url + + +main : Program Model Msg +main = + Node.defineProgram + { init = init + , update = update + , subscriptions = subscriptions + } + + +type alias Model = + { stdout : Stream + , stderr : Stream + , server : Maybe Http.Server + } + + +type Msg + = CreateServerResult (Result Http.ServerError Http.Server) + | GotRequest Http.Request Response + + +init : Environment -> Init.Task { model : Model, command : Cmd Msg } +init env = + Init.await Http.initialize <| \serverPermission -> + Node.startProgram + { model = + { stdout = env.stdout + , stderr = env.stderr + , server = Nothing + } + , command = + Task.attempt CreateServerResult <| + Http.createServer serverPermission + { host = "0.0.0.0" + , port_ = 3000 + } + } + + +update : Msg -> Model -> { model : Model, command : Cmd Msg } +update msg model = + case msg of + CreateServerResult result -> + case result of + Ok server -> + { model = { model | server = Just server } + , command = Stream.sendLine model.stdout + "Server started" + } + Err (ServerError code message) -> + { model = model + , command = Stream.sendLine model.stderr <| + "Server failed to start: " ++ code ++ "\n" ++ message + } + + GotRequest req res -> + let + body = + Url.toString req.url + in + { model = model + , command = + res + |> Response.setStatus 200 + |> Response.setHeader "Content-type" "text/html" + |> Response.setBody ("" ++ body ++ "") + |> Response.send + } + + +subscriptions : Model -> Sub Msg +subscriptions model = + case model.server of + Just server -> + Http.onRequest server GotRequest + + Nothing -> + Sub.none