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:
Dominik Picheta 2015-04-24 17:56:04 +01:00
commit 72b4912c84
3 changed files with 74 additions and 20 deletions

View file

@ -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":