diff options
Diffstat (limited to 'tests/deps/jester-#head/jester/request.nim')
-rw-r--r-- | tests/deps/jester-#head/jester/request.nim | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/tests/deps/jester-#head/jester/request.nim b/tests/deps/jester-#head/jester/request.nim new file mode 100644 index 000000000..1b837d728 --- /dev/null +++ b/tests/deps/jester-#head/jester/request.nim @@ -0,0 +1,184 @@ +import uri, cgi, tables, logging, strutils, re, options + +import jester/private/utils + +when useHttpBeast: + import httpbeast except Settings + import options, httpcore + + type + NativeRequest* = httpbeast.Request +else: + import asynchttpserver + + type + NativeRequest* = asynchttpserver.Request + +type + Request* = object + req: NativeRequest + patternParams: Option[Table[string, string]] + reMatches: array[MaxSubpatterns, string] + settings*: Settings + +proc body*(req: Request): string = + ## Body of the request, only for POST. + ## + ## You're probably looking for ``formData`` + ## instead. + when useHttpBeast: + req.req.body.get("") + else: + req.req.body + +proc headers*(req: Request): HttpHeaders = + ## Headers received with the request. + ## Retrieving these is case insensitive. + when useHttpBeast: + if req.req.headers.isNone: + newHttpHeaders() + else: + req.req.headers.get() + else: + req.req.headers + +proc path*(req: Request): string = + ## Path of request without the query string. + when useHttpBeast: + let p = req.req.path.get("") + let queryStart = p.find('?') + if unlikely(queryStart != -1): + return p[0 .. queryStart-1] + else: + return p + else: + let u = req.req.url + return u.path + +proc reqMethod*(req: Request): HttpMethod = + ## Request method, eg. HttpGet, HttpPost + when useHttpBeast: + req.req.httpMethod.get() + else: + req.req.reqMethod +proc reqMeth*(req: Request): HttpMethod {.deprecated.} = + req.reqMethod + +proc ip*(req: Request): string = + ## IP address of the requesting client. + when useHttpBeast: + result = req.req.ip + else: + result = req.req.hostname + + let headers = req.headers + if headers.hasKey("REMOTE_ADDR"): + result = headers["REMOTE_ADDR"] + if headers.hasKey("x-forwarded-for"): + result = headers["x-forwarded-for"] + +proc params*(req: Request): Table[string, string] = + ## Parameters from the pattern and the query string. + if req.patternParams.isSome(): + result = req.patternParams.get() + else: + result = initTable[string, string]() + + when useHttpBeast: + let query = req.req.path.get("").parseUri().query + else: + let query = req.req.url.query + + try: + for key, val in cgi.decodeData(query): + result[key] = val + except CgiError: + logging.warn("Incorrect query. Got: $1" % [query]) + + let contentType = req.headers.getOrDefault("Content-Type") + if contentType.startswith("application/x-www-form-urlencoded"): + try: + parseUrlQuery(req.body, result) + except: + logging.warn("Could not parse URL query.") + +proc formData*(req: Request): MultiData = + let contentType = req.headers.getOrDefault("Content-Type") + if contentType.startsWith("multipart/form-data"): + result = parseMPFD(contentType, req.body) + +proc matches*(req: Request): array[MaxSubpatterns, string] = + req.reMatches + +proc secure*(req: Request): bool = + if req.headers.hasKey("x-forwarded-proto"): + let proto = req.headers["x-forwarded-proto"] + case proto.toLowerAscii() + of "https": + result = true + of "http": + result = false + else: + logging.warn("Unknown x-forwarded-proto ", proto) + +proc port*(req: Request): int = + if (let p = req.headers.getOrDefault("SERVER_PORT"); p != ""): + result = p.parseInt + else: + result = if req.secure: 443 else: 80 + +proc host*(req: Request): string = + req.headers.getOrDefault("HOST") + +proc appName*(req: Request): string = + ## This is set by the user in ``run``, it is + ## overriden by the "SCRIPT_NAME" scgi + ## parameter. + req.settings.appName + +proc stripAppName(path, appName: string): string = + result = path + if appname.len > 0: + var slashAppName = appName + if slashAppName[0] != '/' and path[0] == '/': + slashAppName = '/' & slashAppName + + if path.startsWith(slashAppName): + if slashAppName.len() == path.len: + return "/" + else: + return path[slashAppName.len .. path.len-1] + else: + raise newException(ValueError, + "Expected script name at beginning of path. Got path: " & + path & " script name: " & slashAppName) + +proc pathInfo*(req: Request): string = + ## This is ``.path`` without ``.appName``. + req.path.stripAppName(req.appName) + +# TODO: Can cookie keys be duplicated? +proc cookies*(req: Request): Table[string, string] = + ## Cookies from the browser. + if (let cookie = req.headers.getOrDefault("Cookie"); cookie != ""): + result = parseCookies(cookie) + else: + result = initTable[string, string]() + +#[ Protected procs ]# + +proc initRequest*(req: NativeRequest, settings: Settings): Request {.inline.} = + Request( + req: req, + settings: settings + ) + +proc getNativeReq*(req: Request): NativeRequest = + req.req + +#[ Only to be used by our route macro. ]# +proc setPatternParams*(req: var Request, p: Table[string, string]) = + req.patternParams = some(p) + +proc setReMatches*(req: var Request, r: array[MaxSubpatterns, string]) = + req.reMatches = r |