all repos — min @ c04ec2ffd416f2832267be48c4aaec0bb7410b85

A small but practical concatenative programming language.

core/server.nim

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
import 
  asynchttpserver,
  asyncdispatch,
  httpclient,
  streams,
  critbits,
  pegs,
  strutils

import
  types,
  parser,
  interpreter,
  utils


proc validUrl(req: Request, url: string): bool =
  return req.url.path == url or req.url.path == url & "/"

proc validMethod(req: Request, meth: string): bool =
  return req.reqMethod == meth

proc exec(req: Request, interpreter: MinInterpreter, hosts: CritBitTree[string]): string {.gcsafe.}=
  let filename = "request"
  let s = newStringStream(req.body)
  var i = interpreter
  i.open(s, filename)
  discard i.parser.getToken() 
  i.interpret()
  result = i.dump()
  i.close()

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\/?$":
    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.} =
    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)

proc post*(url, content: string): string =
  url.postContent(content)