Simple web server

This commit is contained in:
Florian Schroedl
2022-05-04 17:00:00 +02:00
parent f038e4f272
commit 05ecdb1f9e
13 changed files with 209 additions and 7 deletions

96
src/server/server.nim Normal file
View File

@@ -0,0 +1,96 @@
import system/[
io,
]
import std/[
asyncdispatch,
asynchttpserver,
mimetypes,
os,
strformat,
strutils,
sugar,
]
import fp/[
option,
]
import fusion/matching
import ./env
import ./utils
# (GET, (scheme: "", username: "", password: "", hostname: "", port: "", path: "/", query: "", anchor: "", opaque: false, isIpv6: false), {"accept": @["*/*"], "host": @["localhost:45201"], "user-agent": @["curl/7.82.0"]})
{.experimental: "caseStmtMacros".}
type
NimHttpResponse* = tuple[
code: HttpCode,
content: string,
headers: HttpHeaders
]
proc sendNotFound(env: Env, path: seq[string]): NimHttpResponse =
(
code: Http404,
content: "Not Found",
headers: newHttpHeaders({
"Content-Type": "text/html"
}),
)
proc sendStaticFile(env: Env, path: seq[string]): NimHttpResponse =
let mimetype = path
.last()
.map((x: string) => x.splitFile.ext)
.notEmpty()
.map((x: string) => env.mimeTypes.getMimetype(x))
.getOrElse("text/plain")
let filePath = env.htmlRoot.joinPath(path.join("/"))
let file = filePath.readFile()
(
code: Http200,
content: file,
headers: newHttpHeaders({
"Content-Type": mimetype
})
)
proc handleRoute(env: Env, req: Request): NimHttpResponse =
# Handle main route
if req.url.path == "/":
return sendStaticFile(env, path = @["index.html"])
var path = req.url.path.split("/")
path.delete(0)
# Router
return (
case path:
of ["dist", .._]:
sendStaticFile(env, path)
else:
sendNotFound(env, path)
)
proc main {.async.} =
let env = initEnv();
proc cb(req: Request) {.async.} =
echo (req.reqMethod, req.url, req.headers)
let response = handleRoute(env, req)
await req.respond(response.code, response.content , response.headers)
var server = newAsyncHttpServer()
server.listen(Port(env.port))
echo &"Starting server at {env.port}"
while true:
if server.shouldAcceptRequest():
await server.acceptRequest(cb)
else:
# too many concurrent connections, `maxFDs` exceeded wait 500ms for FDs to be closed
await sleepAsync(500)
waitFor main()