Skip to content

Commit

Permalink
improve builtin server perfomance
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethosa committed Oct 9, 2024
1 parent 1105d4d commit 268d770
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
36 changes: 36 additions & 0 deletions src/happyx/ssr/core.nim
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,36 @@ func parsePath*(data: string): Option[string] =
else:
return none(string)

func parsePathWithQueries*(data: string): Option[(string, string)] =
## Parses the request path from the specified data.
if unlikely(data.len == 0):
return

# Find the first ' '.
# We can actually start ahead a little here. Since we know
# the shortest HTTP method: 'GET'/'PUT'.
var i = 2
while data[i] notin {' ', '\0'}:
inc i

if likely(data[i] == ' '):
# Find the second ' '.
inc i # Skip first ' '.
let start = i
var q = -1
while data[i] notin {' ', '\0'}:
if data[i] == '?':
q = i
inc i

if likely(data[i] == ' '):
if q == -1:
return some((data[start..<i], ""))
else:
return some((data[start..<q], data[(q+1)..<i]))
else:
return none((string, string))

func parseHeaders*(data: string): Option[HttpHeaders] =
if unlikely(data.len == 0):
return
Expand Down Expand Up @@ -674,6 +704,12 @@ proc path*(req: Request): Option[string] {.inline.} =
return
parsePath(req.selector.getData(req.client).data)

proc pathWithQueries*(req: Request): Option[(string, string)] {.inline.} =
## Parses the request's data to find the request target.
if unlikely(req.client notin req.selector):
return
parsePathWithQueries(req.selector.getData(req.client).data)

proc headers*(req: Request): Option[HttpHeaders] =
## Parses the request's data to get the headers.
if unlikely(req.client notin req.selector):
Expand Down
16 changes: 12 additions & 4 deletions src/happyx/ssr/server.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1265,11 +1265,19 @@ macro routes*(server: Server, body: untyped = newStmtList()): untyped =
)
elif statement.kind in [nnkVarSection, nnkLetSection]:
variables.add(statement)

let
immutableVars = newNimNode(nnkLetSection).add(
newIdentDefs(ident"urlPath", newEmptyNode(), path),
)
immutableVars =
when enableBuiltin:
newNimNode(nnkLetSection).add(
newNimNode(nnkVarTuple).add(
ident"urlPath", ident"queryRaw", newEmptyNode(), newCall("get", newCall("pathWithQueries", ident"req"))
)
)
else:
newNimNode(nnkLetSection).add(
newIdentDefs(ident"urlPath", newEmptyNode(), path),
)
mutableVars = newNimNode(nnkVarSection)

# immutable variables
Expand Down
5 changes: 5 additions & 0 deletions tests/testc3.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,10 @@ serve("127.0.0.1", 5000):
post "/user":
""""""

get "/some":
# echo req.path.get()
# echo req.pathWithQueries.get()
urlPath

notfound:
"""method not allowed"""

0 comments on commit 268d770

Please sign in to comment.