Making sure all relevant calls are gc safe.
h3rald h3rald@h3rald.com
Sat, 02 Jul 2016 20:12:44 +0200
4 files changed,
29 insertions(+),
22 deletions(-)
M
core/server.nim
→
core/server.nim
@@ -4,7 +4,8 @@ asyncdispatch,
httpclient, streams, critbits, - pegs + pegs, + strutils import types,@@ -19,16 +20,7 @@
proc validMethod(req: Request, meth: string): bool = return req.reqMethod == meth -proc reqPost(req: Request) {.async.}= - if not req.validMethod("POST"): - await req.respond(Http405, "Method Not Allowed: " & req.reqMethod) - -#proc reqUrl(req: Request, url: string) {.async.}= -# if not req.validUrl(url): -# await req.respond(Http400, "Bad Request: POST " & req.url.path) - - -proc exec(req: Request, interpreter: MinInterpreter): string {.gcsafe.}= +proc exec(req: Request, interpreter: MinInterpreter, hosts: CritBitTree[string]): string {.gcsafe.}= let filename = "request" let s = newStringStream(req.body) var i = interpreter@@ -38,20 +30,30 @@ i.interpret()
result = i.dump() i.close() -proc process(req: Request, i: MinInterpreter): string {.gcsafe.} = +proc process(req: Request, i: MinInterpreter, hosts: CritBitTree[string]): string {.gcsafe.} = var matches = @["", "", ""] template route(req, peg: expr, op: stmt): stmt {.immediate.}= if req.url.path.find(peg, matches) != -1: op req.route peg"^\/exec\/?$": - return exec(req, i) + if not req.validMethod("POST"): + raiseServer(Http405, "Method Not Allowed: " & req.reqMethod) + return exec(req, i, hosts) + raiseServer(Http400, "Bad Request: POST "& req.url.path) + proc serve*(port: Port, address = "", interpreter: MinInterpreter) = var hosts: CritBitTree[string] proc handleHttpRequest(req: Request): Future[void] {.async.} = - if not req.validMethod("POST"): - await req.respond(Http405, "Method Not Allowed: " & req.reqMethod) - await req.respond(Http200, req.process(interpreter)) + var res: string + var code: HttpCode = Http200 + try: + res = req.process(interpreter, hosts) + except MinServerError: + let e: MinServerError = (MinServerError)getCurrentException() + res = e.msg + code = e.code + await req.respond(code, res) let server = newAsyncHttpServer() asyncCheck server.serve(port, handleHttpRequest, address)
M
core/types.nim
→
core/types.nim
@@ -1,4 +1,4 @@
-import lexbase, critbits +import lexbase, critbits, httpclient type MinTokenKind* = enum@@ -89,6 +89,8 @@ MinUndefinedError* = ref object of ValueError
MinInvalidError* = ref object of ValueError MinEmptyStackError* = ref object of ValueError MinOutOfBoundsError* = ref object of ValueError + MinServerError* = ref object of SystemError + code*: HttpCode MinRuntimeError* = ref object of SystemError qVal*: seq[MinValue]
M
core/utils.nim
→
core/utils.nim
@@ -1,4 +1,4 @@
-import tables, strutils, macros, critbits +import tables, strutils, macros, critbits, httpclient import types, parser, interpreter proc isSymbol*(s: MinValue): bool =@@ -68,6 +68,9 @@ raise MinRuntimeError(msg: msg, qVal: qVal)
proc raiseEmptyStack*() = raise MinEmptyStackError(msg: "Insufficient items on the stack") + +proc raiseServer*(code: HttpCode, msg: string) = + raise MinServerError(msg: msg, code: code) proc getString*(v: MinValue): string = if v.isSymbol:
M
minim.nim
→
minim.nim
@@ -43,10 +43,10 @@ -i, --interactive Start MiNiM's Read Eval Print Loop"""
proc completionCallback*(str: cstring, completions: ptr linenoiseCompletions) {.cdecl.}= var words = ($str).split(" ") - var w = if words.len > 0: words.pop else: "" - var sep = "" - if words.len > 0: - sep = " " + #var w = if words.len > 0: words.pop else: "" + #var sep = "" + #if words.len > 0: + # sep = " " # TODO REDO #for s in ROOT.symbols.keys: # if startsWith(s, w):