Unofficial utility package for mummy thread server. Various helper functions.
- Version
> 0.1.0requiresmummyversion> 0.4.0or higher. - Version
== 0.8.0supportsmummyversion> 0.3.6or higher.
import std/[json, options]
import mummy, mummy/routers
import mummy_utils
proc indexParams(request: Request) =
# Named parameter from route URL
echo "projectID: " & @"projectID"
# URI query param passed with ?invoiceID=123
echo "invoiceID: " & @"invoiceID"
resp(Http200, %* {"message": "Hello, World!"})
proc indexRedirect(request: Request) =
redirect("/project/123/info")
# redirect(Http301, "/project/123/info")
proc indexHeaders(request: Request) =
var headers: HttpHeaders
if request.cookies("pass") == "1234567890":
setHeader("xauth", "secret")
else:
resp(Http401, "Not authorized")
setHeader("Content-Type", "text/html")
resp(Http200, headers, "<h1>Hello, World!</h1>")
proc indexHead(request: Request) =
resp Http200
proc indexPost(request: Request) =
let urlParam = @"projectID"
if urlParam == "":
resp(Http400, "Missing projectID")
let body = parseJson(request.body)
resp(Http200, ContentType.Text, body["msg"].getStr())
proc indexFile(request: Request) =
sendFile("filepath/" & @"filename")
proc indexMultipart(request: Request) =
var file: string
for entry in request.multipart:
if entry.data.isSome and entry.name == "croppedImage":
let (start, last) = entry.data.get
file = request.body[start .. last]
break
# Do something with file
resp Http204
var router: Router
router.get("/project/@projectID/info", indexParams)
router.get("/redirect", indexRedirect)
router.get("/headers", indexHeaders)
router.head("/headers", indexHead)
router.post("/headers", indexPost)
router.get("/file/@filename", indexFile)
router.post("/multipart", indexMultipart)
let server = newServer(router)
echo "Serving on http://localhost:8080"
server.serve(Port(8080))
var router: Router
router.get("/project/@projectID/info", indexCustom)
router.post("/project/@projectID/info", indexCustom)
router.post("/project/@projectID/info",
proc(request: Request) =
echo "projectID: " & @"projectID"
echo "invoiceID: " & @"invoiceID"
resp(Http200, "Hello, World!")
)Request* = object
params*: StringTableRef ## Parameters from the pattern, but also the
## query string.
body*: string ## Body of the request, only for POST.
headers*: HttpHeaders ## Headers received with the request.
## Retrieving these is case insensitive.
multipart*: seq[MultipartEntry] ## Form data; only present for
## multipart/form-data
host*: string ## Hostname.
secure*: bool ## From X-Forwarded-Proto header.
path*: string ## Path of request.
query*: string ## Query string of request.
cookies*: StringTableRef ## Cookies from the browser.
ip*: string ## IP address of the requesting client.
reqMeth*: HttpMethod ## Request method, eg. HttpGet, HttpPost
echo request.body
echo request.headers["Content-Type"]
echo request.host
echo request.ip
echo request.path
echo request.query
echo request.reqMethod
echo request.secure
echo request.cookies("glid")
echo request.cookies.hasKey("glid")proc body*(request: Request): string =proc host*(request: Request): string =proc ip*(request: Request): string =proc path*(request: Request): string =proc query*(request: Request): string =proc reqMethod*(request: Request): HttpMethod =proc multipart*(request: Request): seq[MultipartEntry] =proc secure*(request: Request): bool =echo request.headers["Content-Type"]
echo request.headers["Content-Typexxx"] # returns empty string
var headers: HttpHeaders
setHeader("Content-Type", "text/plain")proc hasKey*(headers: HttpHeaders, key: string): bool =template setHeader*(field, value: string) =Set header of response. Requires you to initialize the header first.
echo request.cookies("glid")
echo request.cookies.hasKey("glid")
let c = request.cookies
echo c["glid"]proc cookies*(request: Request, cookie: string): string =proc cookies*(request: Request): StringTableRef =Get cookies of request.
template setCookie*(
key, value: string,
domain = "", path = "", expires = "";
noName = false, secure = true, httpOnly = true,
maxAge = none(int),
sameSite = SameSite.Default
) =Sets the cookie - will remove any other cookies with the same name.
template setCookie*(
key, value: string,
expires: DateTime | Time,
domain = "", path = "",
noName = false, secure = true, httpOnly = true,
maxAge = none(int),
sameSite = SameSite.Default
) =Sets the cookie - will remove any other cookies with the same name.
template addCookie*(
key, value: string,
domain = "", path = "", expires = "";
noName = false, secure = true, httpOnly = true,
maxAge = none(int),
sameSite = SameSite.Default
) =Add cookie to response but requires the header to be available.
template addCookie*(
key, value: string,
expires: DateTime | Time,
domain = "", path = "",
noName = false, secure = true, httpOnly = true,
maxAge = none(int),
sameSite = SameSite.Default
) =Add cookie to response but requires the header to be available.
echo request.params("projectID")
echo request.params("invoiceID")
let p = request.params
echo p["projectID"]
echo p.hasKey("invoiceID")template params*(request: Request, s: string): string =template params*(request: Request): StringTableRef =Get params. Is initialized on each call. Includes named route parameters. Returns the value on first match in this order:
- URI path
- URI query
- body data
URI path names parameters are only available in main route Details callback
is available.
echo @"projectID"
echo @"invoiceID"template `@`*(s: string): untyped =Get param. Includes named route parameters. Returns the value on first match in this order:
- URI path
- URI query
- body data
URI path names parameters are only available in main route Details callback
is available.
resp("Hello, World!")
resp(Http200, "Hello, World!")
resp(Http200, ContentType.Html, "Hello, World!")
resp(Http200, @{"Content-Type": "text/plain"}, "Hello, World!")resp(%* {"message": "Hello, World!"})
resp(Http200, %* {"message": "Hello, World!"})
resp(Http200, ContentType.Json, %* {"message": "Hello, World!"})redirect("/project/123/info")
redirect(Http301, "/project/123/info")sendFile("images/logo.png")var headers: HttpHeaders
setHeader("xauth", "1234567890")
setHeader("Content-Type", "text/html")
resp(Http200, headers, "Hello, World!")
# or
var headers: HttpHeaders
setHeader("xauth", "1234567890")
resp(Http200, "Hello, World!") ContentType* = enum
Json = "application/json"
Text = "text/plain"
Html = "text/html; charset=utf-8"If the headers is declared, they will be used in the resp().
template resp*(body: string) =template resp*(httpStatus: HttpCode) =template resp*(httpStatus: HttpCode, body: string) =template resp*(httpStatus: HttpCode, contentType: ContentType, body: string) =template resp*(httpStatus: HttpCode = Http200, headers: HttpHeaders, body: string) =template resp*(body: JsonNode) =template resp*(httpStatus: HttpCode, body: JsonNode) =template resp*(httpStatus: HttpCode, contentType: ContentType, body: JsonNode) =template sendFile*(path: string) =template redirect*(path: string) =template redirect*(httpStatus: HttpCode, path: string) =mummy_utils was developed to ease the transition from jester to mummy.
In mummy_utils you have access to many of the same sugar functions
that jester provides.
Jester
routes:
get "/project/@projectID/info":
echo "projectID: " & @"projectID"
resp "Hello, World!"Mummy #1
var router: Router
router.get("/project/@projectID/info",
proc(request: Request) =
echo "projectID: " & @"projectID"
resp "Hello, World!"
)Mummy #2
var router: Router
router.get("/project/@projectID/info", proc(request: Request) =
echo "projectID: " & @"projectID"
resp "Hello, World!"
)Mummy #3
proc indexCustom(request: Request) =
echo "projectID: " & @"projectID"
resp "Hello, World!"
var router: Router
router.get("/project/@projectID/info", indexCustom)