Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
06ac861c20 | |||
061b0a44fc | |||
be60254227 | |||
c6d02d7db7 |
@@ -1,6 +1,6 @@
|
||||
# Package
|
||||
|
||||
version = "0.4.7"
|
||||
version = "0.4.11"
|
||||
author = "Jonathan Bernard"
|
||||
description = "Jonathan's opinionated extensions and auth layer for Jester."
|
||||
license = "MIT"
|
||||
|
@@ -1,36 +1,56 @@
|
||||
from strutils import isEmptyOrWhitespace
|
||||
from httpcore import HttpCode
|
||||
import std/[httpcore, json, options, strutils]
|
||||
|
||||
type ApiError* = object of CatchableError
|
||||
respMsg*: string
|
||||
respCode*: HttpCode
|
||||
respData*: Option[JsonNode]
|
||||
|
||||
|
||||
proc newApiError*(parent: ref Exception = nil, respCode: HttpCode, respMsg: string, msg = ""): ref ApiError =
|
||||
proc newApiError*(
|
||||
parent: ref Exception = nil,
|
||||
respCode: HttpCode,
|
||||
respMsg: string,
|
||||
respData = none[JsonNode](),
|
||||
msg = ""): ref ApiError =
|
||||
result = newException(ApiError, msg, parent)
|
||||
result.respCode = respCode
|
||||
result.respMsg = respMsg
|
||||
result.respData = respData
|
||||
|
||||
if not parent.isNil:
|
||||
result.trace &= parent.trace
|
||||
|
||||
|
||||
proc raiseApiError*(respCode: HttpCode, respMsg: string, msg = "") =
|
||||
proc raiseApiError*(
|
||||
respCode: HttpCode,
|
||||
respMsg: string,
|
||||
respData = none[JsonNode](),
|
||||
msg = "") =
|
||||
var apiError = newApiError(
|
||||
parent = nil,
|
||||
respCode = respCode,
|
||||
respMsg = respMsg,
|
||||
respData = respData,
|
||||
msg = if msg.isEmptyOrWhitespace: respMsg
|
||||
else: msg)
|
||||
raise apiError
|
||||
|
||||
|
||||
proc raiseApiError*(respCode: HttpCode, parent: ref Exception, respMsg: string = "", msg = "") =
|
||||
proc raiseApiError*(
|
||||
respCode: HttpCode,
|
||||
parent: ref Exception,
|
||||
respMsg: string = "",
|
||||
respData = none[JsonNode](),
|
||||
msg = "") =
|
||||
var apiError = newApiError(
|
||||
parent = parent,
|
||||
respCode = respCode,
|
||||
respMsg =
|
||||
if respMsg.isEmptyOrWhitespace: parent.msg
|
||||
else: respMsg,
|
||||
msg = msg)
|
||||
respData = respData,
|
||||
msg =
|
||||
if msg.isEmptyOrWhitespace: parent.msg
|
||||
else: msg)
|
||||
|
||||
raise apiError
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import std/[json, jsonutils, options, sequtils, strtabs, strutils]
|
||||
import mummy, webby
|
||||
import mummy, webby, uuids
|
||||
|
||||
import std/httpcore except HttpHeaders
|
||||
|
||||
@@ -31,7 +31,7 @@ func initApiResponse*[T](
|
||||
totalItems: totalItems, nextLink: nextLink, prevLink: prevLink)
|
||||
|
||||
|
||||
func `%`*(r: ApiResponse): JsonNode =
|
||||
proc `%`*(r: ApiResponse): JsonNode =
|
||||
result = newJObject()
|
||||
if r.details.isSome: result["details"] = %r.details
|
||||
if r.data.isSome: result["data"] = %r.data
|
||||
@@ -47,6 +47,7 @@ func `$`*(r: ApiResponse): string = $(%r)
|
||||
proc makeCorsHeaders*(
|
||||
allowedMethods: seq[string],
|
||||
allowedOrigins: seq[string],
|
||||
allowedHeaders: Option[seq[string]],
|
||||
reqOrigin = none[string]()): HttpHeaders =
|
||||
|
||||
result =
|
||||
@@ -55,7 +56,12 @@ proc makeCorsHeaders*(
|
||||
"Access-Control-Allow-Origin": reqOrigin.get,
|
||||
"Access-Control-Allow-Credentials": "true",
|
||||
"Access-Control-Allow-Methods": allowedMethods.join(","),
|
||||
"Access-Control-Allow-Headers": "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-CSRF-TOKEN"
|
||||
"Access-Control-Allow-Headers":
|
||||
if allowedHeaders.isSome: allowedHeaders.get.join(",")
|
||||
else:
|
||||
"DNT,User-Agent,X-Requested-With,If-Modified-Since," &
|
||||
"Cache-Control,Content-Type,Range,Authorization,X-CSRF-TOKEN," &
|
||||
"traceparent,tracestate,X-Request-ID,X-Correlation-ID",
|
||||
}
|
||||
else:
|
||||
if reqOrigin.isSome:
|
||||
@@ -67,8 +73,16 @@ proc makeCorsHeaders*(
|
||||
proc makeCorsHeaders*(
|
||||
allowedMethods: seq[HttpMethod],
|
||||
allowedOrigins: seq[string],
|
||||
allowedHeaders: Option[seq[string]],
|
||||
reqOrigin = none[string]()): HttpHeaders =
|
||||
makeCorsHeaders(allowedMethods.mapIt($it), allowedOrigins, reqOrigin )
|
||||
makeCorsHeaders(allowedMethods.mapIt($it), allowedOrigins, allowedHeaders, reqOrigin )
|
||||
|
||||
|
||||
proc makeCorsHeaders*[T: HttpMethod or string](
|
||||
allowedMethods: seq[T],
|
||||
allowedOrigins: seq[string],
|
||||
reqOrigin = none[string]()): HttpHeaders =
|
||||
makeCorsHeaders(allowedMethods, allowedOrigins, none[seq[string]](), reqOrigin )
|
||||
|
||||
|
||||
func origin*(req: Request): Option[string] =
|
||||
@@ -76,6 +90,40 @@ func origin*(req: Request): Option[string] =
|
||||
else: none[string]()
|
||||
|
||||
|
||||
func traceparent*(req: Request): Option[string] =
|
||||
## Extract the traceparent from the request headers, if present.
|
||||
if req.headers.contains("traceparent"):
|
||||
return some(req.headers["traceparent"])
|
||||
else:
|
||||
return none[string]()
|
||||
|
||||
|
||||
proc makeTraceContextHeaders*(req: Request, traceParentId: string): HttpHeaders =
|
||||
var headers = HttpHeaders(@[])
|
||||
|
||||
if req.headers.contains("traceparent"):
|
||||
# If the traceparent header is present, we should update it with our
|
||||
# parent-id.
|
||||
let traceparentParts = req.headers["traceparent"].split("-")
|
||||
if traceparentParts.len != 4:
|
||||
headers["traceparent"] = "00-$#-$#-00" % [
|
||||
replace($genUUID(), "-", ""), # trace-id
|
||||
traceParentId, # parent-id
|
||||
]
|
||||
|
||||
else:
|
||||
headers["traceparent"] = "00-$#-$#-$#" % [
|
||||
traceparentParts[1], # trace-id
|
||||
traceParentId, # parent-id
|
||||
traceparentParts[3], # flags
|
||||
]
|
||||
|
||||
if req.headers.contains("tracestate"):
|
||||
headers["tracestate"] = req.headers["tracestate"]
|
||||
|
||||
return headers
|
||||
|
||||
|
||||
proc respondWithRawJson*(
|
||||
req: Request,
|
||||
body: JsonNode,
|
||||
|
Reference in New Issue
Block a user