implement frame reader for buffered payload (#55)

now the frame can choose to read from buffered
payload if available or read from asyncstream
if the buffer is empty
This commit is contained in:
andri lim 2021-06-15 02:41:31 +07:00 committed by GitHub
parent 99d643013b
commit f80278aeee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 11 deletions

View File

@ -56,6 +56,35 @@ proc mask*(
template remainder*(frame: Frame): uint64 =
frame.length - frame.consumed
proc read*(frame: Frame,
reader: AsyncStreamReader,
pbytes: pointer,
nbytes: int): Future[int] {.async.} =
# read data from buffered payload if available
# e.g. data processed by extensions
var readLen = 0
if frame.offset < frame.data.len:
readLen = min(frame.data.len - frame.offset, nbytes)
copyMem(pbytes, addr frame.data[frame.offset], readLen)
frame.offset += readLen
var pbuf = cast[ptr UncheckedArray[byte]](pbytes)
if readLen < nbytes:
let len = min(nbytes - readLen, frame.remainder.int - readLen)
readLen += await reader.readOnce(addr pbuf[readLen], len)
if frame.mask and readLen > 0:
# unmask data using offset
mask(
pbuf.toOpenArray(0, readLen - 1),
frame.maskKey,
frame.consumed.int
)
frame.consumed += readLen.uint64
return readLen
proc encode*(
frame: Frame,
extensions: seq[Ext] = @[]): Future[seq[byte]] {.async.} =

View File

@ -359,23 +359,13 @@ proc recv*(
let len = min(ws.frame.remainder.int, size - consumed)
if len > 0:
trace "Reading bytes from frame stream", len
let read = await ws.stream.reader.readOnce(addr pbuffer[consumed], len)
let read = await ws.frame.read(ws.stream.reader, addr pbuffer[consumed], len)
if read <= 0:
trace "Didn't read any bytes, breaking"
break
trace "Read data from frame", read
if ws.frame.mask:
trace "Unmasking frame"
# unmask data using offset
mask(
pbuffer.toOpenArray(consumed, (consumed + read) - 1),
ws.frame.maskKey,
ws.frame.consumed.int)
consumed += read
ws.frame.consumed += read.uint64
# all has been consumed from the frame
# read the next frame

View File

@ -61,6 +61,7 @@ type
maskKey*: MaskKey ## Masking key
length*: uint64 ## Message size.
consumed*: uint64 ## how much has been consumed from the frame
offset*: int ## offset of buffered payload data
StatusCodes* = distinct range[0..4999]