Introduce FutureVar[T] to make recvLineInto safer.
FutureVar[T] is a new distinct Future type which is designed to be used for situations where the highest performance is needed. It reduces the number of Future allocations needed. It acts as a replacement for 'var' params in async procs. This commit modifies @def-'s PR in order to make it safer. The recvLineInto procedure has been modified to take a ``FutureVar[string]`` param instead of a ``ptr string`` param.
This commit is contained in:
parent
62e1b3e2e3
commit
72b4912c84
3 changed files with 74 additions and 20 deletions
|
|
@ -148,7 +148,8 @@ proc processClient(client: AsyncSocket, address: string,
|
|||
var request: Request
|
||||
request.url = initUri()
|
||||
request.headers = newStringTable(modeCaseInsensitive)
|
||||
var line = newStringOfCap(80)
|
||||
var lineFut = newFutureVar[string]("asynchttpserver.processClient")
|
||||
lineFut.mget() = newStringOfCap(80)
|
||||
var key, value = ""
|
||||
|
||||
while not client.isClosed:
|
||||
|
|
@ -161,14 +162,15 @@ proc processClient(client: AsyncSocket, address: string,
|
|||
request.client = client
|
||||
|
||||
# First line - GET /path HTTP/1.1
|
||||
line.setLen(0)
|
||||
await client.recvLineInto(addr line) # TODO: Timeouts.
|
||||
if line == "":
|
||||
lineFut.mget().setLen(0)
|
||||
lineFut.clean()
|
||||
await client.recvLineInto(lineFut) # TODO: Timeouts.
|
||||
if lineFut.mget == "":
|
||||
client.close()
|
||||
return
|
||||
|
||||
var i = 0
|
||||
for linePart in line.split(' '):
|
||||
for linePart in lineFut.mget.split(' '):
|
||||
case i
|
||||
of 0: request.reqMethod.shallowCopy(linePart.normalize)
|
||||
of 1: parseUri(linePart, request.url)
|
||||
|
|
@ -180,20 +182,21 @@ proc processClient(client: AsyncSocket, address: string,
|
|||
"Invalid request protocol. Got: " & linePart)
|
||||
continue
|
||||
else:
|
||||
await request.respond(Http400, "Invalid request. Got: " & line)
|
||||
await request.respond(Http400, "Invalid request. Got: " & lineFut.mget)
|
||||
continue
|
||||
inc i
|
||||
|
||||
# Headers
|
||||
while true:
|
||||
i = 0
|
||||
line.setLen(0)
|
||||
await client.recvLineInto(addr line)
|
||||
lineFut.mget.setLen(0)
|
||||
lineFut.clean()
|
||||
await client.recvLineInto(lineFut)
|
||||
|
||||
if line == "":
|
||||
if lineFut.mget == "":
|
||||
client.close(); return
|
||||
if line == "\c\L": break
|
||||
let (key, value) = parseHeader(line)
|
||||
if lineFut.mget == "\c\L": break
|
||||
let (key, value) = parseHeader(lineFut.mget)
|
||||
request.headers[key] = value
|
||||
|
||||
if request.reqMethod == "post":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue