Add apiutils.
This commit is contained in:
parent
3777e3dbbd
commit
4e0d06bb67
@ -1,7 +1,5 @@
|
||||
# This is just an example to get you started. A typical library package
|
||||
# exports the main API in this file. Note that you cannot rename this file
|
||||
# but you can remove it if you wish.
|
||||
|
||||
proc add*(x, y: int): int =
|
||||
## Adds two files together.
|
||||
return x + y
|
||||
import buffoonery/apierror,
|
||||
buffoonery/apiutils,
|
||||
buffoonery/auth,
|
||||
buffoonery/jsonutils
|
||||
export apierror, apiutils, auth, jsonutils
|
||||
|
96
src/buffoonery/apiutils.nim
Normal file
96
src/buffoonery/apiutils.nim
Normal file
@ -0,0 +1,96 @@
|
||||
import std/json, std/logging, std/strutils, std/sequtils
|
||||
import jester, namespaced_logging
|
||||
|
||||
import ./apierror
|
||||
|
||||
const CONTENT_TYPE_JSON* = "application/json"
|
||||
|
||||
var logNs {.threadvar.}: LoggingNamespace
|
||||
|
||||
template log(): untyped =
|
||||
if logNs.isNil: logNs = initLoggingNamespace("buffoonery/apiutils", lvlDebug)
|
||||
logNs
|
||||
|
||||
## Response Utilities
|
||||
template halt*(
|
||||
code: HttpCode,
|
||||
headers: RawHeaders,
|
||||
content: string) =
|
||||
## Immediately replies with the specified request. This means any further
|
||||
## code will not be executed after calling this template in the current
|
||||
## route.
|
||||
bind TCActionSend, newHttpHeaders
|
||||
result[0] = CallbackAction.TCActionSend
|
||||
result[1] = code
|
||||
result[2] = if isSome(result[2]): some(result[2].get & headers)
|
||||
else: some(headers)
|
||||
result[3] = content
|
||||
result.matched = true
|
||||
break allRoutes
|
||||
|
||||
template sendJsonResp*(
|
||||
code: HttpCode,
|
||||
body: string = "",
|
||||
knownOrigins: seq[string],
|
||||
headersToSend: RawHeaders) =
|
||||
## Immediately send a JSON response and stop processing the request.
|
||||
let reqOrigin =
|
||||
if headers(request).hasKey("Origin"): $(headers(request)["Origin"])
|
||||
else: ""
|
||||
|
||||
let corsHeaders =
|
||||
if knownOrigins.contains(reqOrigin):
|
||||
@{
|
||||
"Access-Control-Allow-Origin": reqOrigin,
|
||||
"Access-Control-Allow-Credentials": "true",
|
||||
"Access-Control-Allow-Methods": $(reqMethod(request)),
|
||||
"Access-Control-Allow-Headers": "Authorization,X-CSRF-TOKEN"
|
||||
}
|
||||
else:
|
||||
log().warn "Unrecognized Origin '" & reqOrigin & "', excluding CORS headers."
|
||||
@{:}
|
||||
|
||||
halt(
|
||||
code,
|
||||
cast[RawHeaders](headersToSend) & corsHeaders & @{
|
||||
"Content-Type": CONTENT_TYPE_JSON,
|
||||
"Cache-Control": "no-cache"
|
||||
},
|
||||
body
|
||||
)
|
||||
|
||||
proc makeDataBody*(data: JsonNode): string = $(%*{"details":"","data":data })
|
||||
proc makeStatusBody*(details: string): string = $(%*{"details":details})
|
||||
|
||||
template sendErrorResp*(err: ref ApiError, knownOrigins: seq[string]): void =
|
||||
log().debug err.respMsg & ( if err.msg.len > 0: ": " & err.msg else: "")
|
||||
if not err.parent.isNil: log().debug " original exception: " & err.parent.msg
|
||||
sendJsonResp(err.respCode, makeStatusBody(err.respMsg), knownOrigins, @{:})
|
||||
|
||||
## CORS support
|
||||
template sendOptionsResp*(
|
||||
allowedMethods: seq[HttpMethod],
|
||||
knownOrigins: seq[string]) =
|
||||
|
||||
let reqOrigin =
|
||||
if headers(request).hasKey("Origin"): $(headers(request)["Origin"])
|
||||
else: ""
|
||||
|
||||
let corsHeaders =
|
||||
if knownOrigins.contains(reqOrigin):
|
||||
@{
|
||||
"Access-Control-Allow-Origin": reqOrigin,
|
||||
"Access-Control-Allow-Credentials": "true",
|
||||
"Access-Control-Allow-Methods": allowedMethods.mapIt($it).join(", "),
|
||||
"Access-Control-Allow-Headers": "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-CSRF-TOKEN"
|
||||
}
|
||||
else:
|
||||
log().warn "Unrecognized Origin '" & reqOrigin & "', excluding CORS headers."
|
||||
log().debug "Valid origins: " & knownOrigins.join(", ")
|
||||
@{:}
|
||||
|
||||
halt(
|
||||
Http200,
|
||||
corsHeaders,
|
||||
""
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user