all repos — min @ 638cb7ac58499c87dcd1a0d232e68bb831f90a48

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
import 
  asynchttpserver,
  asyncdispatch,
  httpclient,
  streams,
  critbits,
  pegs

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 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.}=
  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): 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)

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))
  let server = newAsyncHttpServer()
  asyncCheck server.serve(port, handleHttpRequest, address)

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