Merge branch 'devel' into fix_time_offset_in_times_js
This commit is contained in:
commit
04646052ab
10 changed files with 97 additions and 48 deletions
|
|
@ -133,8 +133,8 @@ doc.file = """<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
|
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
|
||||||
|
|
||||||
<!-- Google fonts -->
|
<!-- Google fonts -->
|
||||||
<link href='http://fonts.googleapis.com/css?family=Raleway:400,600,900' rel='stylesheet' type='text/css'/>
|
<link href='https://fonts.googleapis.com/css?family=Raleway:400,600,900' rel='stylesheet' type='text/css'/>
|
||||||
<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
|
<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
|
||||||
|
|
||||||
<!-- CSS -->
|
<!-- CSS -->
|
||||||
<title>$title</title>
|
<title>$title</title>
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,16 @@ type
|
||||||
readOnly*: bool
|
readOnly*: bool
|
||||||
options*: seq[OptionElement]
|
options*: seq[OptionElement]
|
||||||
|
|
||||||
|
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
||||||
|
HtmlElement* = ref object of Element
|
||||||
|
contentEditable*: string
|
||||||
|
isContentEditable*: bool
|
||||||
|
dir*: string
|
||||||
|
offsetHeight*: int
|
||||||
|
offsetWidth*: int
|
||||||
|
offsetLeft*: int
|
||||||
|
offsetTop*: int
|
||||||
|
|
||||||
LinkElement* = ref LinkObj
|
LinkElement* = ref LinkObj
|
||||||
LinkObj {.importc.} = object of ElementObj
|
LinkObj {.importc.} = object of ElementObj
|
||||||
target*: cstring
|
target*: cstring
|
||||||
|
|
@ -270,6 +280,8 @@ type
|
||||||
wordSpacing*: cstring
|
wordSpacing*: cstring
|
||||||
zIndex*: int
|
zIndex*: int
|
||||||
|
|
||||||
|
# TODO: A lot of the fields in Event belong to a more specific type of event.
|
||||||
|
# TODO: Should we clean this up?
|
||||||
Event* = ref EventObj
|
Event* = ref EventObj
|
||||||
EventObj {.importc.} = object of RootObj
|
EventObj {.importc.} = object of RootObj
|
||||||
target*: Node
|
target*: Node
|
||||||
|
|
@ -310,6 +322,20 @@ type
|
||||||
SUBMIT*: int
|
SUBMIT*: int
|
||||||
UNLOAD*: int
|
UNLOAD*: int
|
||||||
|
|
||||||
|
TouchList* {.importc.} = ref object of RootObj
|
||||||
|
length*: int
|
||||||
|
|
||||||
|
TouchEvent* {.importc.} = ref object of Event
|
||||||
|
changedTouches*, targetTouches*, touches*: TouchList
|
||||||
|
|
||||||
|
Touch* {.importc.} = ref object of RootObj
|
||||||
|
identifier*: int
|
||||||
|
screenX*, screenY*, clientX*, clientY*, pageX*, pageY*: int
|
||||||
|
target*: Element
|
||||||
|
radiusX*, radiusY*: int
|
||||||
|
rotationAngle*: int
|
||||||
|
force*: float
|
||||||
|
|
||||||
Location* = ref LocationObj
|
Location* = ref LocationObj
|
||||||
LocationObj {.importc.} = object of RootObj
|
LocationObj {.importc.} = object of RootObj
|
||||||
hash*: cstring
|
hash*: cstring
|
||||||
|
|
@ -488,6 +514,10 @@ proc setAttribute*(s: Style, attr, value: cstring, caseSensitive=false)
|
||||||
# Event "methods"
|
# Event "methods"
|
||||||
proc preventDefault*(ev: Event)
|
proc preventDefault*(ev: Event)
|
||||||
|
|
||||||
|
# TouchEvent "methods"
|
||||||
|
proc identifiedTouch*(list: TouchList): Touch
|
||||||
|
proc item*(list: TouchList, i: int): Touch
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
|
||||||
|
|
@ -109,12 +109,17 @@ type
|
||||||
Dirent* {.importc: "struct dirent",
|
Dirent* {.importc: "struct dirent",
|
||||||
header: "<dirent.h>", final, pure.} = object ## dirent_t struct
|
header: "<dirent.h>", final, pure.} = object ## dirent_t struct
|
||||||
d_ino*: Ino ## File serial number.
|
d_ino*: Ino ## File serial number.
|
||||||
when defined(linux) or defined(macosx) or defined(bsd):
|
when defined(dragonfly):
|
||||||
|
# DragonflyBSD doesn't have `d_reclen` field.
|
||||||
|
d_type*: uint8
|
||||||
|
elif defined(linux) or defined(macosx) or defined(freebsd) or
|
||||||
|
defined(netbsd) or defined(openbsd):
|
||||||
d_reclen*: cshort ## Length of this record. (not POSIX)
|
d_reclen*: cshort ## Length of this record. (not POSIX)
|
||||||
d_type*: int8 ## Type of file; not supported by all filesystem types.
|
d_type*: int8 ## Type of file; not supported by all filesystem types.
|
||||||
## (not POSIX)
|
## (not POSIX)
|
||||||
when defined(linux) or defined(bsd):
|
when defined(linux) or defined(openbsd):
|
||||||
d_off*: Off ## Not an offset. Value that ``telldir()`` would return.
|
d_off*: Off ## Not an offset. Value that ``telldir()`` would return.
|
||||||
|
|
||||||
d_name*: array[0..255, char] ## Name of entry.
|
d_name*: array[0..255, char] ## Name of entry.
|
||||||
|
|
||||||
Tflock* {.importc: "struct flock", final, pure,
|
Tflock* {.importc: "struct flock", final, pure,
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ import httpcore
|
||||||
|
|
||||||
export httpcore except parseHeader
|
export httpcore except parseHeader
|
||||||
|
|
||||||
|
const
|
||||||
|
maxLine = 8*1024
|
||||||
|
|
||||||
# TODO: If it turns out that the decisions that asynchttpserver makes
|
# TODO: If it turns out that the decisions that asynchttpserver makes
|
||||||
# explicitly, about whether to close the client sockets or upgrade them are
|
# explicitly, about whether to close the client sockets or upgrade them are
|
||||||
# wrong, then add a return value which determines what to do for the callback.
|
# wrong, then add a return value which determines what to do for the callback.
|
||||||
|
|
@ -97,6 +100,18 @@ proc respond*(req: Request, code: HttpCode, content: string,
|
||||||
|
|
||||||
if headers != nil:
|
if headers != nil:
|
||||||
msg.addHeaders(headers)
|
msg.addHeaders(headers)
|
||||||
|
msg.add("Content-Length: ")
|
||||||
|
# this particular way saves allocations:
|
||||||
|
msg.add content.len
|
||||||
|
msg.add "\c\L\c\L"
|
||||||
|
msg.add(content)
|
||||||
|
result = req.client.send(msg)
|
||||||
|
|
||||||
|
proc respondError(req: Request, code: HttpCode): Future[void] =
|
||||||
|
## Responds to the request with the specified ``HttpCode``.
|
||||||
|
let content = $code
|
||||||
|
var msg = "HTTP/1.1 " & content & "\c\L"
|
||||||
|
|
||||||
msg.add("Content-Length: " & $content.len & "\c\L\c\L")
|
msg.add("Content-Length: " & $content.len & "\c\L\c\L")
|
||||||
msg.add(content)
|
msg.add(content)
|
||||||
result = req.client.send(msg)
|
result = req.client.send(msg)
|
||||||
|
|
@ -139,12 +154,16 @@ proc processClient(client: AsyncSocket, address: string,
|
||||||
for i in 0..1:
|
for i in 0..1:
|
||||||
lineFut.mget().setLen(0)
|
lineFut.mget().setLen(0)
|
||||||
lineFut.clean()
|
lineFut.clean()
|
||||||
await client.recvLineInto(lineFut) # TODO: Timeouts.
|
await client.recvLineInto(lineFut, maxLength=maxLine) # TODO: Timeouts.
|
||||||
|
|
||||||
if lineFut.mget == "":
|
if lineFut.mget == "":
|
||||||
client.close()
|
client.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if lineFut.mget.len > maxLine:
|
||||||
|
await request.respondError(Http413)
|
||||||
|
client.close()
|
||||||
|
return
|
||||||
if lineFut.mget != "\c\L":
|
if lineFut.mget != "\c\L":
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -157,19 +176,17 @@ proc processClient(client: AsyncSocket, address: string,
|
||||||
# TODO: this is likely slow.
|
# TODO: this is likely slow.
|
||||||
request.reqMethod = parseEnum[HttpMethod]("http" & linePart)
|
request.reqMethod = parseEnum[HttpMethod]("http" & linePart)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
asyncCheck request.respond(Http400, "Invalid request method. Got: " &
|
asyncCheck request.respondError(Http400)
|
||||||
linePart)
|
|
||||||
continue
|
continue
|
||||||
of 1: parseUri(linePart, request.url)
|
of 1: parseUri(linePart, request.url)
|
||||||
of 2:
|
of 2:
|
||||||
try:
|
try:
|
||||||
request.protocol = parseProtocol(linePart)
|
request.protocol = parseProtocol(linePart)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
asyncCheck request.respond(Http400,
|
asyncCheck request.respondError(Http400)
|
||||||
"Invalid request protocol. Got: " & linePart)
|
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
await request.respond(Http400, "Invalid request. Got: " & lineFut.mget)
|
await request.respondError(Http400)
|
||||||
continue
|
continue
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
|
|
@ -178,10 +195,13 @@ proc processClient(client: AsyncSocket, address: string,
|
||||||
i = 0
|
i = 0
|
||||||
lineFut.mget.setLen(0)
|
lineFut.mget.setLen(0)
|
||||||
lineFut.clean()
|
lineFut.clean()
|
||||||
await client.recvLineInto(lineFut)
|
await client.recvLineInto(lineFut, maxLength=maxLine)
|
||||||
|
|
||||||
if lineFut.mget == "":
|
if lineFut.mget == "":
|
||||||
client.close(); return
|
client.close(); return
|
||||||
|
if lineFut.mget.len > maxLine:
|
||||||
|
await request.respondError(Http413)
|
||||||
|
client.close(); return
|
||||||
if lineFut.mget == "\c\L": break
|
if lineFut.mget == "\c\L": break
|
||||||
let (key, value) = parseHeader(lineFut.mget)
|
let (key, value) = parseHeader(lineFut.mget)
|
||||||
request.headers[key] = value
|
request.headers[key] = value
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ template createCb(retFutureSym, iteratorNameSym,
|
||||||
else:
|
else:
|
||||||
next.callback = cb
|
next.callback = cb
|
||||||
except:
|
except:
|
||||||
|
futureVarCompletions
|
||||||
|
|
||||||
if retFutureSym.finished:
|
if retFutureSym.finished:
|
||||||
# Take a look at tasyncexceptions for the bug which this fixes.
|
# Take a look at tasyncexceptions for the bug which this fixes.
|
||||||
# That test explains it better than I can here.
|
# That test explains it better than I can here.
|
||||||
|
|
@ -47,7 +49,6 @@ template createCb(retFutureSym, iteratorNameSym,
|
||||||
else:
|
else:
|
||||||
retFutureSym.fail(getCurrentException())
|
retFutureSym.fail(getCurrentException())
|
||||||
|
|
||||||
futureVarCompletions
|
|
||||||
cb()
|
cb()
|
||||||
#{.pop.}
|
#{.pop.}
|
||||||
proc generateExceptionCheck(futSym,
|
proc generateExceptionCheck(futSym,
|
||||||
|
|
@ -123,12 +124,16 @@ template createVar(result: var NimNode, futSymName: string,
|
||||||
result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
|
result.add newVarStmt(futSym, asyncProc) # -> var future<x> = y
|
||||||
useVar(result, futSym, valueReceiver, rootReceiver, fromNode)
|
useVar(result, futSym, valueReceiver, rootReceiver, fromNode)
|
||||||
|
|
||||||
proc createFutureVarCompletions(futureVarIdents: seq[NimNode]): NimNode
|
proc createFutureVarCompletions(futureVarIdents: seq[NimNode],
|
||||||
{.compileTime.} =
|
fromNode: NimNode): NimNode {.compileTime.} =
|
||||||
result = newStmtList()
|
result = newNimNode(nnkStmtList, fromNode)
|
||||||
# Add calls to complete each FutureVar parameter.
|
# Add calls to complete each FutureVar parameter.
|
||||||
for ident in futureVarIdents:
|
for ident in futureVarIdents:
|
||||||
# Only complete them if they have not been completed already by the user.
|
# Only complete them if they have not been completed already by the user.
|
||||||
|
# TODO: Once https://github.com/nim-lang/Nim/issues/5617 is fixed.
|
||||||
|
# TODO: Add line info to the complete() call!
|
||||||
|
# In the meantime, this was really useful for debugging :)
|
||||||
|
#result.add(newCall(newIdentNode("echo"), newStrLitNode(fromNode.lineinfo)))
|
||||||
result.add newIfStmt(
|
result.add newIfStmt(
|
||||||
(
|
(
|
||||||
newCall(newIdentNode("not"),
|
newCall(newIdentNode("not"),
|
||||||
|
|
@ -145,6 +150,10 @@ proc processBody(node, retFutureSym: NimNode,
|
||||||
case node.kind
|
case node.kind
|
||||||
of nnkReturnStmt:
|
of nnkReturnStmt:
|
||||||
result = newNimNode(nnkStmtList, node)
|
result = newNimNode(nnkStmtList, node)
|
||||||
|
|
||||||
|
# As I've painfully found out, the order here really DOES matter.
|
||||||
|
result.add createFutureVarCompletions(futureVarIdents, node)
|
||||||
|
|
||||||
if node[0].kind == nnkEmpty:
|
if node[0].kind == nnkEmpty:
|
||||||
if not subTypeIsVoid:
|
if not subTypeIsVoid:
|
||||||
result.add newCall(newIdentNode("complete"), retFutureSym,
|
result.add newCall(newIdentNode("complete"), retFutureSym,
|
||||||
|
|
@ -158,8 +167,6 @@ proc processBody(node, retFutureSym: NimNode,
|
||||||
else:
|
else:
|
||||||
result.add newCall(newIdentNode("complete"), retFutureSym, x)
|
result.add newCall(newIdentNode("complete"), retFutureSym, x)
|
||||||
|
|
||||||
result.add createFutureVarCompletions(futureVarIdents)
|
|
||||||
|
|
||||||
result.add newNimNode(nnkReturnStmt, node).add(newNilLit())
|
result.add newNimNode(nnkReturnStmt, node).add(newNilLit())
|
||||||
return # Don't process the children of this return stmt
|
return # Don't process the children of this return stmt
|
||||||
of nnkCommand, nnkCall:
|
of nnkCommand, nnkCall:
|
||||||
|
|
@ -347,6 +354,8 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
futureVarIdents, nil)
|
futureVarIdents, nil)
|
||||||
# don't do anything with forward bodies (empty)
|
# don't do anything with forward bodies (empty)
|
||||||
if procBody.kind != nnkEmpty:
|
if procBody.kind != nnkEmpty:
|
||||||
|
procBody.add(createFutureVarCompletions(futureVarIdents, nil))
|
||||||
|
|
||||||
if not subtypeIsVoid:
|
if not subtypeIsVoid:
|
||||||
procBody.insert(0, newNimNode(nnkPragma).add(newIdentNode("push"),
|
procBody.insert(0, newNimNode(nnkPragma).add(newIdentNode("push"),
|
||||||
newNimNode(nnkExprColonExpr).add(newNimNode(nnkBracketExpr).add(
|
newNimNode(nnkExprColonExpr).add(newNimNode(nnkBracketExpr).add(
|
||||||
|
|
@ -366,8 +375,6 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
# -> complete(retFuture)
|
# -> complete(retFuture)
|
||||||
procBody.add(newCall(newIdentNode("complete"), retFutureSym))
|
procBody.add(newCall(newIdentNode("complete"), retFutureSym))
|
||||||
|
|
||||||
procBody.add(createFutureVarCompletions(futureVarIdents))
|
|
||||||
|
|
||||||
var closureIterator = newProc(iteratorNameSym, [newIdentNode("FutureBase")],
|
var closureIterator = newProc(iteratorNameSym, [newIdentNode("FutureBase")],
|
||||||
procBody, nnkIteratorDef)
|
procBody, nnkIteratorDef)
|
||||||
closureIterator[4] = newNimNode(nnkPragma, prc[6]).add(newIdentNode("closure"))
|
closureIterator[4] = newNimNode(nnkPragma, prc[6]).add(newIdentNode("closure"))
|
||||||
|
|
@ -377,7 +384,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
#var cbName = newIdentNode("cb")
|
#var cbName = newIdentNode("cb")
|
||||||
var procCb = getAst createCb(retFutureSym, iteratorNameSym,
|
var procCb = getAst createCb(retFutureSym, iteratorNameSym,
|
||||||
newStrLitNode(prc[0].getName),
|
newStrLitNode(prc[0].getName),
|
||||||
createFutureVarCompletions(futureVarIdents))
|
createFutureVarCompletions(futureVarIdents, nil))
|
||||||
outerProcBody.add procCb
|
outerProcBody.add procCb
|
||||||
|
|
||||||
# -> return retFuture
|
# -> return retFuture
|
||||||
|
|
@ -398,7 +405,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
if procBody.kind != nnkEmpty:
|
if procBody.kind != nnkEmpty:
|
||||||
result[6] = outerProcBody
|
result[6] = outerProcBody
|
||||||
#echo(treeRepr(result))
|
#echo(treeRepr(result))
|
||||||
#if prc[0].getName == "beta":
|
#if prc[0].getName == "recvLineInto":
|
||||||
# echo(toStrLit(result))
|
# echo(toStrLit(result))
|
||||||
|
|
||||||
macro async*(prc: untyped): untyped =
|
macro async*(prc: untyped): untyped =
|
||||||
|
|
|
||||||
|
|
@ -464,8 +464,7 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
|
||||||
## The partial line **will be lost**.
|
## The partial line **will be lost**.
|
||||||
##
|
##
|
||||||
## The ``maxLength`` parameter determines the maximum amount of characters
|
## The ``maxLength`` parameter determines the maximum amount of characters
|
||||||
## that can be read before a ``ValueError`` is raised. This prevents Denial
|
## that can be read. ``resString`` will be truncated after that.
|
||||||
## of Service (DOS) attacks.
|
|
||||||
##
|
##
|
||||||
## **Warning**: The ``Peek`` flag is not yet implemented.
|
## **Warning**: The ``Peek`` flag is not yet implemented.
|
||||||
##
|
##
|
||||||
|
|
@ -519,10 +518,7 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
|
||||||
socket.currPos.inc()
|
socket.currPos.inc()
|
||||||
|
|
||||||
# Verify that this isn't a DOS attack: #3847.
|
# Verify that this isn't a DOS attack: #3847.
|
||||||
if resString.mget.len > maxLength:
|
if resString.mget.len > maxLength: break
|
||||||
let msg = "recvLine received more than the specified `maxLength` " &
|
|
||||||
"allowed."
|
|
||||||
raise newException(ValueError, msg)
|
|
||||||
else:
|
else:
|
||||||
var c = ""
|
var c = ""
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -546,10 +542,7 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
|
||||||
resString.mget.add c
|
resString.mget.add c
|
||||||
|
|
||||||
# Verify that this isn't a DOS attack: #3847.
|
# Verify that this isn't a DOS attack: #3847.
|
||||||
if resString.mget.len > maxLength:
|
if resString.mget.len > maxLength: break
|
||||||
let msg = "recvLine received more than the specified `maxLength` " &
|
|
||||||
"allowed."
|
|
||||||
raise newException(ValueError, msg)
|
|
||||||
resString.complete()
|
resString.complete()
|
||||||
|
|
||||||
proc recvLine*(socket: AsyncSocket,
|
proc recvLine*(socket: AsyncSocket,
|
||||||
|
|
@ -569,8 +562,7 @@ proc recvLine*(socket: AsyncSocket,
|
||||||
## The partial line **will be lost**.
|
## The partial line **will be lost**.
|
||||||
##
|
##
|
||||||
## The ``maxLength`` parameter determines the maximum amount of characters
|
## The ``maxLength`` parameter determines the maximum amount of characters
|
||||||
## that can be read before a ``ValueError`` is raised. This prevents Denial
|
## that can be read. The result is truncated after that.
|
||||||
## of Service (DOS) attacks.
|
|
||||||
##
|
##
|
||||||
## **Warning**: The ``Peek`` flag is not yet implemented.
|
## **Warning**: The ``Peek`` flag is not yet implemented.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -418,7 +418,7 @@ proc spawn*(call: expr): expr {.magic: "Spawn".}
|
||||||
proc pinnedSpawn*(id: ThreadId; call: expr): expr {.magic: "Spawn".}
|
proc pinnedSpawn*(id: ThreadId; call: expr): expr {.magic: "Spawn".}
|
||||||
## always spawns a new task on the worker thread with ``id``, so that
|
## always spawns a new task on the worker thread with ``id``, so that
|
||||||
## the 'call' is **always** executed on
|
## the 'call' is **always** executed on
|
||||||
## the this thread. 'call' has to be proc call 'p(...)' where 'p'
|
## the thread. 'call' has to be proc call 'p(...)' where 'p'
|
||||||
## is gcsafe and has a return type that is either 'void' or compatible
|
## is gcsafe and has a return type that is either 'void' or compatible
|
||||||
## with ``FlowVar[T]``.
|
## with ``FlowVar[T]``.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ proc `$`*(code: HttpCode): string =
|
||||||
proc `==`*(a, b: HttpCode): bool {.borrow.}
|
proc `==`*(a, b: HttpCode): bool {.borrow.}
|
||||||
|
|
||||||
proc `==`*(rawCode: string, code: HttpCode): bool =
|
proc `==`*(rawCode: string, code: HttpCode): bool =
|
||||||
return rawCode.toLower() == ($code).toLower()
|
return cmpIgnoreCase(rawCode, $code) == 0
|
||||||
|
|
||||||
proc is2xx*(code: HttpCode): bool =
|
proc is2xx*(code: HttpCode): bool =
|
||||||
## Determines whether ``code`` is a 2xx HTTP status code.
|
## Determines whether ``code`` is a 2xx HTTP status code.
|
||||||
|
|
@ -304,7 +304,7 @@ proc is5xx*(code: HttpCode): bool =
|
||||||
return code.int in {500 .. 599}
|
return code.int in {500 .. 599}
|
||||||
|
|
||||||
proc `$`*(httpMethod: HttpMethod): string =
|
proc `$`*(httpMethod: HttpMethod): string =
|
||||||
return (system.`$`(httpMethod))[4 .. ^1].toUpper()
|
return (system.`$`(httpMethod))[4 .. ^1].toUpperAscii()
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var test = newHttpHeaders()
|
var test = newHttpHeaders()
|
||||||
|
|
|
||||||
|
|
@ -1010,8 +1010,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
|
||||||
## the specified time an ETimeout exception will be raised.
|
## the specified time an ETimeout exception will be raised.
|
||||||
##
|
##
|
||||||
## The ``maxLength`` parameter determines the maximum amount of characters
|
## The ``maxLength`` parameter determines the maximum amount of characters
|
||||||
## that can be read before a ``ValueError`` is raised. This prevents Denial
|
## that can be read. The result is truncated after that.
|
||||||
## of Service (DOS) attacks.
|
|
||||||
##
|
##
|
||||||
## **Warning**: Only the ``SafeDisconn`` flag is currently supported.
|
## **Warning**: Only the ``SafeDisconn`` flag is currently supported.
|
||||||
|
|
||||||
|
|
@ -1047,10 +1046,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
|
||||||
add(line.string, c)
|
add(line.string, c)
|
||||||
|
|
||||||
# Verify that this isn't a DOS attack: #3847.
|
# Verify that this isn't a DOS attack: #3847.
|
||||||
if line.string.len > maxLength:
|
if line.string.len > maxLength: break
|
||||||
let msg = "recvLine received more than the specified `maxLength` " &
|
|
||||||
"allowed."
|
|
||||||
raise newException(ValueError, msg)
|
|
||||||
|
|
||||||
proc recvLine*(socket: Socket, timeout = -1,
|
proc recvLine*(socket: Socket, timeout = -1,
|
||||||
flags = {SocketFlag.SafeDisconn},
|
flags = {SocketFlag.SafeDisconn},
|
||||||
|
|
@ -1069,8 +1065,7 @@ proc recvLine*(socket: Socket, timeout = -1,
|
||||||
## the specified time an ETimeout exception will be raised.
|
## the specified time an ETimeout exception will be raised.
|
||||||
##
|
##
|
||||||
## The ``maxLength`` parameter determines the maximum amount of characters
|
## The ``maxLength`` parameter determines the maximum amount of characters
|
||||||
## that can be read before a ``ValueError`` is raised. This prevents Denial
|
## that can be read. The result is truncated after that.
|
||||||
## of Service (DOS) attacks.
|
|
||||||
##
|
##
|
||||||
## **Warning**: Only the ``SafeDisconn`` flag is currently supported.
|
## **Warning**: Only the ``SafeDisconn`` flag is currently supported.
|
||||||
result = ""
|
result = ""
|
||||||
|
|
|
||||||
|
|
@ -508,8 +508,8 @@ else:
|
||||||
freeAddrInfo(aiList)
|
freeAddrInfo(aiList)
|
||||||
# for some reason Windows select doesn't return both
|
# for some reason Windows select doesn't return both
|
||||||
# descriptors from first call, so we need to make 2 calls
|
# descriptors from first call, so we need to make 2 calls
|
||||||
discard selector.select(100)
|
discard selector.select(1000)
|
||||||
var rcm = selector.select(100)
|
var rcm = selector.select(1000)
|
||||||
assert(len(rcm) == 2)
|
assert(len(rcm) == 2)
|
||||||
|
|
||||||
var sockAddress = SockAddr()
|
var sockAddress = SockAddr()
|
||||||
|
|
@ -526,7 +526,7 @@ else:
|
||||||
|
|
||||||
selector.updateHandle(client_socket, {Event.Read})
|
selector.updateHandle(client_socket, {Event.Read})
|
||||||
|
|
||||||
var rc2 = selector.select(100)
|
var rc2 = selector.select(1000)
|
||||||
assert(len(rc2) == 1)
|
assert(len(rc2) == 1)
|
||||||
|
|
||||||
var read_count = recv(server2_socket, addr buffer[0], 128, 0)
|
var read_count = recv(server2_socket, addr buffer[0], 128, 0)
|
||||||
|
|
@ -595,7 +595,7 @@ else:
|
||||||
proc event_wait_thread(event: SelectEvent) {.thread.} =
|
proc event_wait_thread(event: SelectEvent) {.thread.} =
|
||||||
var selector = newSelector[int]()
|
var selector = newSelector[int]()
|
||||||
selector.registerEvent(event, 1)
|
selector.registerEvent(event, 1)
|
||||||
var rc = selector.select(500)
|
var rc = selector.select(1500)
|
||||||
if len(rc) == 1:
|
if len(rc) == 1:
|
||||||
inc(counter)
|
inc(counter)
|
||||||
selector.unregister(event)
|
selector.unregister(event)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue