Modular multithreading HTTP/1.1 + WebSocket server framework
# nim r --d:release --d:threadsafe thisexample
import cgi, guildenstern/[dispatcher, httpserver]
proc handleGet() =
echo "method: ", getMethod()
echo "uri: ", getUri()
if isUri("/favicon.ico"): reply(Http204)
else:
let html = """
<!doctype html><title>GuildenStern Example</title><body>
<form action="http:https://localhost:5051" method="post" accept-charset="utf-8">
<input name="say" value="Hi"><button>Send"""
reply(html)
proc handlePost() =
echo "client said: ", readData(getBody()).getOrDefault("say")
reply(Http303, ["location: " & http.headers.getOrDefault("origin")])
let getserver = newHttpServer(handleGet, contenttype = NoBody)
let postserver = newHttpServer(handlePost, loglevel = INFO, headerfields = ["origin"])
getserver.start(5050)
postserver.start(5051, threadpoolsize = 20, maxactivethreadcount = 10)
joinThreads(getserver.thread, postserver.thread)
https://olliniinivaara.github.io/GuildenStern/7/theindex.html
https://olliniinivaara.github.io/GuildenStern/6.1.0/index.html
atlas use GuildenStern
- step 1: Install WSL
- step 2: atlas use GuildenStern
- All threads are initialized when their server is started (instead of when they are first used), making the system more fail-fast
- - is an accepted char in header field names
- WebSocketServer code clean-up: WebSocketContext removed; opcode not anymore visible to end users
- Minor fixes and improvements
- receiveInChunks iterator renamed to receiveStream
- maxrequestlength renamed to bufferlength
- newHttpServer does not anymore take hascontent parameter, but instead:
- newHttpServer takes contenttype parameter:
- Compact (the default mode): Equivalent to previous hasContent=true mode, where whole request body must fit into the buffer
- NoBody: Equivalent to previous hasContent=false mode, for optimized handling of requests like GET that do not have a body
- Streaming: Equivalent to previous StreamingServer, where you have to read the body yourself using the receiveStream iterator
- startDownload-continueDownload-finishDownload combo renamed to replyStartChunked-replyContinueChunked-replyFinishChunked
- parseHeaders and parseAllHeaders obsoleted
- newHttpServer takes headerfields parameter, listing header fields that you need
- in request handlers http.headers StringTableRef is automatically populated with needed header key-value pairs
- handles multipart/form-data for you as neatly parsed
- operates in streaming manner, allowing huge uploads without blowing up RAM
- If you do not accept a connection (reply false in upgradeCallback), a HTTP 400 reply is now automatically sent before the socket is closed
- PONG is now automatically replied to PINGs, sendPong proc is removed
- default reply values changed, now timeoutsecs = 10, sleepmillisecs = 10
- if all in-flight receivers are blocking, now suspends for (sleepmillisecs * in-flight receiver count) milliseconds
- fixed isMessage bug