nim-websock/ws/stream.nim
2021-05-22 12:12:31 +07:00

58 lines
1.7 KiB
Nim

import pkg/[chronos,
chronos/apps/http/httpserver,
chronos/timer,
chronicles,
httputils]
import strutils
const
HeaderSep = @[byte('\c'), byte('\L'), byte('\c'), byte('\L')]
HttpHeadersTimeout = timer.seconds(120) # timeout for receiving headers (120 sec)
MaxHttpHeadersSize = 8192 # maximum size of HTTP headers in octets
proc readHeaders*(rstream: AsyncStreamReader): Future[seq[byte]] {.async.} =
var buffer = newSeq[byte](MaxHttpHeadersSize)
var error = false
try:
let hlenfut = rstream.readUntil(
addr buffer[0], MaxHttpHeadersSize,
sep = HeaderSep)
let ores = await withTimeout(hlenfut, HttpHeadersTimeout)
if not ores:
# Timeout
debug "Timeout expired while receiving headers",
address = rstream.tsource.remoteAddress()
error = true
else:
let hlen = hlenfut.read()
buffer.setLen(hlen)
except AsyncStreamLimitError:
# size of headers exceeds `MaxHttpHeadersSize`
debug "Maximum size of headers limit reached",
address = rstream.tsource.remoteAddress()
error = true
except AsyncStreamIncompleteError:
# remote peer disconnected
debug "Remote peer disconnected", address = rstream.tsource.remoteAddress()
error = true
except AsyncStreamError as exc:
debug "Problems with networking", address = rstream.tsource.remoteAddress(),
error = exc.msg
error = true
if error:
buffer.setLen(0)
return buffer
proc closeWait*(wsStream: AsyncStream) {.async.} =
await allFutures(
wsStream.writer.closeWait(),
wsStream.reader.closeWait())
await allFutures(
wsStream.writer.tsource.closeWait(),
wsStream.reader.tsource.closeWait())
# TODO: Implement stream read and write wrapper.