Skip to content

Commit a079117

Browse files
committed
little optimizations [ssr]
1 parent 8c58560 commit a079117

File tree

5 files changed

+214
-116
lines changed

5 files changed

+214
-116
lines changed

bindings/python/happyx/happyx.pyd

-146 KB
Binary file not shown.

happyx.nimble

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
description = "Macro-oriented asynchronous web-framework written with ♥"
44
author = "HapticX"
5-
version = "3.8.13"
5+
version = "3.8.14"
66
license = "MIT"
77
srcDir = "src"
88
installExt = @["nim"]

src/happyx/core/constants.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const
101101
# Framework version
102102
HpxMajor* = 3
103103
HpxMinor* = 8
104-
HpxPatch* = 13
104+
HpxPatch* = 14
105105
HpxVersion* = $HpxMajor & "." & $HpxMinor & "." & $HpxPatch
106106

107107

src/happyx/ssr/cors.nim

Lines changed: 199 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import
1717
strutils,
1818
strformat,
1919
# Happyx
20-
../core/[exceptions]
20+
../core/[exceptions, constants]
2121

2222

2323

@@ -29,114 +29,207 @@ type
2929
allowMethods*: string
3030

3131

32-
var currentCORSRuntime* = CORSObj()
3332

34-
proc setCors*(allowOrigins: string = "*", allowMethods: string = "*",
35-
allowHeaders: string = "*", credentials: bool = true) {.gcsafe.} =
36-
{.cast(gcsafe).}:
37-
currentCORSRuntime.allowCredentials = credentials
38-
currentCORSRuntime.allowOrigins = @[allowOrigins]
39-
currentCORSRuntime.allowMethods = allowMethods
40-
currentCORSRuntime.allowHeaders = allowHeaders
33+
when not defined(js) and not (exportJvm or exportPython or defined(napibuild)):
34+
var currentCORS {. compileTime .} = CORSObj()
35+
macro addCORSHeaders*(headers: HttpHeaders) =
36+
let
37+
allowCredentials = currentCORS.allowCredentials
38+
allowHeaders= currentCORS.allowHeaders
39+
allowOrigins= currentCORS.allowOrigins
40+
allowMethods= currentCORS.allowMethods
41+
result = quote do:
42+
`headers`["Access-Control-Allow-Credentials"] = $`allowCredentials`
43+
if `allowHeaders`.len > 0:
44+
`headers`["Access-Control-Allow-Headers"] = `allowHeaders`
45+
if `allowMethods`.len > 0:
46+
`headers`["Access-Control-Allow-Methods"] = `allowMethods`
47+
if `allowOrigins`.len > 0:
48+
`headers`["Access-Control-Allow-Origin"] = `allowOrigins`
49+
50+
macro regCORS*(body: untyped): untyped =
51+
## Register CORS
52+
for statement in body:
53+
if statement.kind == nnkCall and statement[1].kind == nnkStmtList:
54+
let
55+
name = statement[0]
56+
val = statement[1][0]
57+
case $name
58+
of "credentials":
59+
if val.kind == nnkIdent and $val in ["on", "off", "yes", "no", "true", "false"]:
60+
currentCORS.allowCredentials = parseBool($val)
61+
continue
62+
of "methods":
63+
if val.kind in [nnkStrLit, nnkTripleStrLit]:
64+
currentCORS.allowMethods = $val
65+
continue
66+
elif val.kind == nnkBracket:
67+
var methods: seq[string] = @[]
68+
for i in val.children:
69+
if i.kind in [nnkStrLit, nnkTripleStrLit]:
70+
methods.add($i)
71+
else:
72+
throwDefect(
73+
HpxCorsDefect,
74+
fmt"invalid regCORS methods syntax: ",
75+
lineInfoObj(val)
76+
)
77+
currentCORS.allowMethods = methods.join(",")
78+
continue
79+
of "headers":
80+
if val.kind in [nnkStrLit, nnkTripleStrLit]:
81+
currentCORS.allowHeaders = $val
82+
continue
83+
elif val.kind == nnkBracket:
84+
var headers: seq[string] = @[]
85+
for i in val.children:
86+
if i.kind in [nnkStrLit, nnkTripleStrLit]:
87+
headers.add($i)
88+
else:
89+
throwDefect(
90+
HpxCorsDefect,
91+
fmt"invalid regCORS headers syntax: ",
92+
lineInfoObj(val)
93+
)
94+
currentCORS.allowMethods = headers.join(",")
95+
continue
96+
of "origins":
97+
if val.kind in [nnkStrLit, nnkTripleStrLit]:
98+
currentCORS.allowOrigins = @[$val]
99+
continue
100+
elif val.kind == nnkBracket:
101+
var origins: seq[string] = @[]
102+
for i in val.children:
103+
if i.kind in [nnkStrLit, nnkTripleStrLit]:
104+
origins.add($i)
105+
else:
106+
throwDefect(
107+
HpxCorsDefect,
108+
fmt"invalid regCORS origins syntax: ",
109+
lineInfoObj(val)
110+
)
111+
currentCORS.allowOrigins = origins
112+
continue
113+
else:
114+
throwDefect(
115+
HpxCorsDefect,
116+
fmt"invalid regCORS statement syntax: ",
117+
lineInfoObj(statement)
118+
)
119+
120+
throwDefect(
121+
HpxCorsDefect,
122+
fmt"invalid regCORS syntax: ",
123+
lineInfoObj(statement)
124+
)
125+
else:
126+
var currentCORSRuntime* = CORSObj()
127+
proc setCors*(allowOrigins: string = "*", allowMethods: string = "*",
128+
allowHeaders: string = "*", credentials: bool = true) {.gcsafe.} =
129+
{.cast(gcsafe).}:
130+
currentCORSRuntime.allowCredentials = credentials
131+
currentCORSRuntime.allowOrigins = @[allowOrigins]
132+
currentCORSRuntime.allowMethods = allowMethods
133+
currentCORSRuntime.allowHeaders = allowHeaders
41134

42-
proc getCors*(): CORSObj {.gcsafe.} =
43-
{.gcsafe.}:
44-
return currentCORSRuntime
135+
proc getCors*(): CORSObj {.gcsafe.} =
136+
{.gcsafe.}:
137+
return currentCORSRuntime
45138

46139

47-
macro addCORSHeaders*(host: string, headers: HttpHeaders) =
48-
result = quote do:
49-
let cors = getCors()
50-
`headers`["Access-Control-Allow-Credentials"] = $cors.allowCredentials
51-
if cors.allowHeaders.len > 0:
52-
`headers`["Access-Control-Allow-Headers"] = cors.allowHeaders
53-
if cors.allowMethods.len > 0:
54-
`headers`["Access-Control-Allow-Methods"] = cors.allowMethods
55-
if cors.allowOrigins.len > 0:
56-
for origin in cors.allowOrigins:
57-
if origin == "*":
58-
`headers`["Access-Control-Allow-Origin"] = "*"
59-
break
60-
elif origin == `host`:
61-
`headers`["Access-Control-Allow-Origin"] = origin
62-
break
63-
if not `headers`.hasKey("Access-Control-Allow-Origin"):
64-
`headers`["Access-Control-Allow-Origin"] = cors.allowOrigins[0]
140+
macro addCORSHeaders*(host: string, headers: HttpHeaders) =
141+
result = quote do:
142+
let cors = getCors()
143+
`headers`["Access-Control-Allow-Credentials"] = $cors.allowCredentials
144+
if cors.allowHeaders.len > 0:
145+
`headers`["Access-Control-Allow-Headers"] = cors.allowHeaders
146+
if cors.allowMethods.len > 0:
147+
`headers`["Access-Control-Allow-Methods"] = cors.allowMethods
148+
if cors.allowOrigins.len > 0:
149+
for origin in cors.allowOrigins:
150+
if origin == "*":
151+
`headers`["Access-Control-Allow-Origin"] = "*"
152+
break
153+
elif origin == `host`:
154+
`headers`["Access-Control-Allow-Origin"] = origin
155+
break
156+
if not `headers`.hasKey("Access-Control-Allow-Origin"):
157+
`headers`["Access-Control-Allow-Origin"] = cors.allowOrigins[0]
65158

66159

67-
macro regCORS*(body: untyped): untyped =
68-
## Register CORS
69-
result = newCall("setCors")
70-
for statement in body:
71-
if statement.kind == nnkCall and statement[1].kind == nnkStmtList:
72-
let
73-
name = statement[0]
74-
val = statement[1][0]
75-
case $name
76-
of "credentials":
77-
if val.kind == nnkIdent and $val in ["on", "off", "yes", "no", "true", "false"]:
78-
result.add(newNimNode(nnkExprEqExpr).add(ident"credentials", newLit(parseBool($val))))
79-
continue
80-
of "methods":
81-
if val.kind in [nnkStrLit, nnkTripleStrLit]:
82-
result.add(newNimNode(nnkExprEqExpr).add(ident"allowMethods", newLit($val)))
83-
continue
84-
elif val.kind == nnkBracket:
85-
var methods: seq[string] = @[]
86-
for i in val.children:
87-
if i.kind in [nnkStrLit, nnkTripleStrLit]:
88-
methods.add($i)
89-
else:
90-
throwDefect(
91-
HpxCorsDefect,
92-
fmt"invalid regCORS methods syntax: ",
93-
lineInfoObj(val)
94-
)
95-
result.add(newNimNode(nnkExprEqExpr).add(ident"allowMethods", newLit(methods.join(","))))
96-
continue
97-
of "headers":
98-
if val.kind in [nnkStrLit, nnkTripleStrLit]:
99-
result.add(newNimNode(nnkExprEqExpr).add(ident"allowHeaders", newLit($val)))
100-
continue
101-
elif val.kind == nnkBracket:
102-
var headers: seq[string] = @[]
103-
for i in val.children:
104-
if i.kind in [nnkStrLit, nnkTripleStrLit]:
105-
headers.add($i)
106-
else:
107-
throwDefect(
108-
HpxCorsDefect,
109-
fmt"invalid regCORS headers syntax: ",
110-
lineInfoObj(val)
111-
)
112-
result.add(newNimNode(nnkExprEqExpr).add(ident"allowHeaders", newLit(headers.join(","))))
113-
continue
114-
of "origins":
115-
if val.kind in [nnkStrLit, nnkTripleStrLit]:
116-
result.add(newNimNode(nnkExprEqExpr).add(ident"allowOrigins", newLit($val)))
117-
continue
118-
elif val.kind == nnkBracket:
119-
var origins: seq[string] = @[]
120-
for i in val.children:
121-
if i.kind in [nnkStrLit, nnkTripleStrLit]:
122-
origins.add($i)
123-
else:
124-
throwDefect(
125-
HpxCorsDefect,
126-
fmt"invalid regCORS origins syntax: ",
127-
lineInfoObj(val)
128-
)
129-
result.add(newNimNode(nnkExprEqExpr).add(ident"allowOrigins", newLit(origins.join(","))))
130-
continue
131-
else:
132-
throwDefect(
133-
HpxCorsDefect,
134-
fmt"invalid regCORS statement syntax: ",
135-
lineInfoObj(statement)
136-
)
137-
138-
throwDefect(
139-
HpxCorsDefect,
140-
fmt"invalid regCORS syntax: ",
141-
lineInfoObj(statement)
142-
)
160+
macro regCORS*(body: untyped): untyped =
161+
## Register CORS
162+
result = newCall("setCors")
163+
for statement in body:
164+
if statement.kind == nnkCall and statement[1].kind == nnkStmtList:
165+
let
166+
name = statement[0]
167+
val = statement[1][0]
168+
case $name
169+
of "credentials":
170+
if val.kind == nnkIdent and $val in ["on", "off", "yes", "no", "true", "false"]:
171+
result.add(newNimNode(nnkExprEqExpr).add(ident"credentials", newLit(parseBool($val))))
172+
continue
173+
of "methods":
174+
if val.kind in [nnkStrLit, nnkTripleStrLit]:
175+
result.add(newNimNode(nnkExprEqExpr).add(ident"allowMethods", newLit($val)))
176+
continue
177+
elif val.kind == nnkBracket:
178+
var methods: seq[string] = @[]
179+
for i in val.children:
180+
if i.kind in [nnkStrLit, nnkTripleStrLit]:
181+
methods.add($i)
182+
else:
183+
throwDefect(
184+
HpxCorsDefect,
185+
fmt"invalid regCORS methods syntax: ",
186+
lineInfoObj(val)
187+
)
188+
result.add(newNimNode(nnkExprEqExpr).add(ident"allowMethods", newLit(methods.join(","))))
189+
continue
190+
of "headers":
191+
if val.kind in [nnkStrLit, nnkTripleStrLit]:
192+
result.add(newNimNode(nnkExprEqExpr).add(ident"allowHeaders", newLit($val)))
193+
continue
194+
elif val.kind == nnkBracket:
195+
var headers: seq[string] = @[]
196+
for i in val.children:
197+
if i.kind in [nnkStrLit, nnkTripleStrLit]:
198+
headers.add($i)
199+
else:
200+
throwDefect(
201+
HpxCorsDefect,
202+
fmt"invalid regCORS headers syntax: ",
203+
lineInfoObj(val)
204+
)
205+
result.add(newNimNode(nnkExprEqExpr).add(ident"allowHeaders", newLit(headers.join(","))))
206+
continue
207+
of "origins":
208+
if val.kind in [nnkStrLit, nnkTripleStrLit]:
209+
result.add(newNimNode(nnkExprEqExpr).add(ident"allowOrigins", newLit($val)))
210+
continue
211+
elif val.kind == nnkBracket:
212+
var origins: seq[string] = @[]
213+
for i in val.children:
214+
if i.kind in [nnkStrLit, nnkTripleStrLit]:
215+
origins.add($i)
216+
else:
217+
throwDefect(
218+
HpxCorsDefect,
219+
fmt"invalid regCORS origins syntax: ",
220+
lineInfoObj(val)
221+
)
222+
result.add(newNimNode(nnkExprEqExpr).add(ident"allowOrigins", newLit(origins.join(","))))
223+
continue
224+
else:
225+
throwDefect(
226+
HpxCorsDefect,
227+
fmt"invalid regCORS statement syntax: ",
228+
lineInfoObj(statement)
229+
)
230+
231+
throwDefect(
232+
HpxCorsDefect,
233+
fmt"invalid regCORS syntax: ",
234+
lineInfoObj(statement)
235+
)

src/happyx/ssr/server.nim

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ template start*(server: Server): untyped =
361361
when enableDebug or exportPython or defined(napibuild):
362362
info "Server started at http://" & `server`.address & ":" & $`server`.port
363363
when not declared(handleRequest):
364-
proc handleRequest(req: Request) {.async.} =
364+
proc handleRequest(req: Request): Future[void] {.async.} =
365365
discard
366366
when enableHttpx:
367367
run(handleRequest, `server`.instance)
@@ -408,10 +408,13 @@ template answer*(
408408
## return "Hello, world!"
409409
##
410410
var h = headers
411-
when enableHttpBeast or enableHttpx:
412-
addCORSHeaders(req.ip, h)
411+
when exportJvm or exportPython or defined(napibuild):
412+
when enableHttpBeast or enableHttpx:
413+
addCORSHeaders(req.ip, h)
414+
else:
415+
addCORSHeaders(req.hostname, h)
413416
else:
414-
addCORSHeaders(req.hostname, h)
417+
h.addCORSHeaders()
415418
when declared(outHeaders):
416419
for key, val in outHeaders.pairs():
417420
h[key] = val
@@ -519,10 +522,9 @@ template answerHtml*(req: Request, data: string | TagRef, code: HttpCode = Http2
519522
## "Hello, world!"
520523
##
521524
when data is string:
522-
let d = data
525+
answer(req, data, code, headers)
523526
else:
524-
let d = $data
525-
answer(req, d, code, headers)
527+
answer(req, $data, code, headers)
526528

527529

528530
when enableHttpx or enableHttpBeast:
@@ -748,7 +750,10 @@ macro routes*(server: Server, body: untyped = newStmtList()): untyped =
748750
notFoundNode = newEmptyNode()
749751
procStmt = newProc(
750752
ident"handleRequest",
751-
[newEmptyNode(), newIdentDefs(ident"req", ident"Request")],
753+
[
754+
newNimNode(nnkBracketExpr).add(ident"Future", ident"void"),
755+
newIdentDefs(ident"req", ident"Request")
756+
],
752757
when enableSafeRequests:
753758
newNimNode(nnkTryStmt).add(
754759
stmtList,

0 commit comments

Comments
 (0)