diff options
author | Emery Hemingway <ehmry@posteo.net> | 2018-08-07 17:36:56 +0200 |
---|---|---|
committer | Emery Hemingway <ehmry@posteo.net> | 2018-08-08 07:48:24 +0200 |
commit | 817e4bb2fe0538a60f169d37e254b30e3dc3ab1d (patch) | |
tree | aa57c10fb5fa8ed69a646f47323135ba8ea31b64 | |
parent | 9b9cfa7306d696961cc6fd590ca72c08f66bdcb3 (diff) | |
download | Nim-817e4bb2fe0538a60f169d37e254b30e3dc3ab1d.tar.gz |
AsyncHttpClient: return from requests before body completion
Store the body completion future at the client and wait for it to complete before issuing additional requests. This allows the body FutureStream reader to drain the stream and read buffers to be freed asynchronously. Fix #8109
-rw-r--r-- | lib/pure/httpclient.nim | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 8b4fb0f8c..72de72718 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -807,6 +807,7 @@ type lastProgressReport: float when SocketType is AsyncSocket: bodyStream: FutureStream[string] + parseBodyFut: Future[void] else: bodyStream: Stream getBody: bool ## When `false`, the body is never read in requestAux. @@ -1066,10 +1067,14 @@ proc parseResponse(client: HttpClient | AsyncHttpClient, if getBody: when client is HttpClient: client.bodyStream = newStringStream() + result.bodyStream = client.bodyStream + parseBody(client, result.headers, result.version) else: client.bodyStream = newFutureStream[string]("parseResponse") - await parseBody(client, result.headers, result.version) - result.bodyStream = client.bodyStream + result.bodyStream = client.bodyStream + assert(client.parseBodyFut.isNil or client.parseBodyFut.finished) + client.parseBodyFut = parseBody(client, result.headers, result.version) + # do not wait here for the body request to complete proc newConnection(client: HttpClient | AsyncHttpClient, url: Uri) {.multisync.} = @@ -1159,6 +1164,12 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string, # Helper that actually makes the request. Does not handle redirects. let requestUrl = parseUri(url) + when client is AsyncHttpClient: + if not client.parseBodyFut.isNil: + # let the current operation finish before making another request + await client.parseBodyFut + client.parseBodyFut = nil + await newConnection(client, requestUrl) let effectiveHeaders = client.headers.override(headers) |