~seanld/silk

857d6dffd767fcdb5cc0cadeca56d0c1b804e9c4 — Sean Wilkerson 5 months ago fb3207c static-middleware v0.4.2
Add default handler
5 files changed, 37 insertions(+), 10 deletions(-)

M src/silk.nim
M src/silk/headers.nim
M src/silk/router.nim
M src/silk/serverconfig.nim
A src/silk/sugar.nim
M src/silk.nim => src/silk.nim +3 -1
@@ 10,6 10,7 @@ import ./silk/headers
import ./silk/context
import ./silk/router
import ./silk/middleware
import ./silk/sugar

export tables.`[]`, tables.`[]=`
export nativesockets.Port


@@ 21,6 22,7 @@ export context
export router
export serverconfig
export middleware
export sugar

type Server* = ref object
  config*: ServerConfig


@@ 79,7 81,7 @@ proc dispatchClient(s: Server, client: AsyncSocket) {.async.} =

  # Dispatch context to router to obtain a relevant `Response`.
  if not skip:
    await s.router.dispatchRoute(req.path, ctx)
    await s.router.dispatchRoute(s.config, req.path, ctx)

  # Send response through middleware pipeline.
  for mw in s.middleware:

M src/silk/headers.nim => src/silk/headers.nim +2 -1
@@ 22,7 22,8 @@ proc `$`*(h: Response): string =
  for k, v in pairs(h.headerFields):
    responseHeader.add(k & ": " & v & "\r\n")

  responseHeader.add("\r\n" & h.content)
  if h.content != "":
    responseHeader.add("\r\n" & h.content)

  return responseHeader


M src/silk/router.nim => src/silk/router.nim +12 -8
@@ 6,17 6,14 @@ from std/strutils import split, contains
import ./context
import ./headers
import ./middleware
import ./status
import ./serverconfig
import ./sugar

type PathParams = TableRef[string, string]
type RouteHandler* = proc(ctx: Context) {.async.}
type RouterEntryHandle = tuple[handler: RouteHandler, middleware: seq[Middleware]]

template handler*(code: untyped): untyped =
  proc(ctx{.inject.}: Context) {.async.} = code

template handler*(name: untyped, code: untyped): untyped =
  proc name(ctx{.inject.}: Context) {.async.} = code

type Node = ref object
  part: string
  handle: RouterEntryHandle


@@ 127,12 124,19 @@ proc DELETE*(r: Router, path: string, handler: RouteHandler, middleware: seq[Mid
  var newPath = Path(path)
  r.registerHandlerRoute("DELETE", newPath, handler, middleware)

proc defaultHandler(ctx: Context) {.async.} =
  ctx.noContent(STATUS_NOT_FOUND)

type RoutingError = object of CatchableError

proc dispatchRoute*(r: Router, path: Path, ctx: Context) {.async.} =
proc dispatchRoute*(r: Router, cfg: ServerConfig, path: Path, ctx: Context) {.async.} =
  let searchResults = r.routeTrees[ctx.req.action].search(path, ctx.params)
  if searchResults.node == nil or not searchResults.matched:
    raise newException(RoutingError, "Could not match route")
    if cfg.defaultHandler != nil:
      await cfg.defaultHandler(ctx)
    else:
      raise newException(RoutingError, "Could not match route")
    return

  var skip = false


M src/silk/serverconfig.nim => src/silk/serverconfig.nim +9 -0
@@ 6,6 6,13 @@
from std/math import `^`
from std/nativesockets import Port

import ./context
import ./status
import ./sugar

handler defaultHandler:
  ctx.noContent(STATUS_NOT_FOUND)

type ServerConfig* = object
  host*: string
  port*: Port


@@ 18,3 25,5 @@ type ServerConfig* = object
  # When `true`, keep program alive, and log errors to loggers. If `false`,
  # let the error kill the program.
  keepAlive* = true

  defaultHandler* = defaultHandler

A src/silk/sugar.nim => src/silk/sugar.nim +11 -0
@@ 0,0 1,11 @@
import std/asyncdispatch

import ./context

export asyncdispatch

template handler*(code: untyped): untyped =
  proc(ctx{.inject.}: Context) {.async.} = code

template handler*(name: untyped, code: untyped): untyped =
  proc name(ctx{.inject.}: Context) {.async.} = code