Merge pull request #8559 from ehmry/fix_8109

AsyncHttpClient: return from requests before body completion
This commit is contained in:
Dominik Picheta 2018-08-08 12:27:20 +01:00 • committed by GitHub
commit af4f4425e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -807,6 +807,7 @@ type
lastProgressReport: float lastProgressReport: float
when SocketType is AsyncSocket: when SocketType is AsyncSocket:
bodyStream: FutureStream[string] bodyStream: FutureStream[string]
parseBodyFut: Future[void]
else: else:
bodyStream: Stream bodyStream: Stream
getBody: bool ## When `false`, the body is never read in requestAux. getBody: bool ## When `false`, the body is never read in requestAux.
@ -1066,10 +1067,14 @@ proc parseResponse(client: HttpClient | AsyncHttpClient,
if getBody: if getBody:
when client is HttpClient: when client is HttpClient:
client.bodyStream = newStringStream() client.bodyStream = newStringStream()
result.bodyStream = client.bodyStream
parseBody(client, result.headers, result.version)
else: else:
client.bodyStream = newFutureStream[string]("parseResponse") 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, proc newConnection(client: HttpClient | AsyncHttpClient,
url: Uri) {.multisync.} = url: Uri) {.multisync.} =
@ -1159,6 +1164,12 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
# Helper that actually makes the request. Does not handle redirects. # Helper that actually makes the request. Does not handle redirects.
let requestUrl = parseUri(url) 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) await newConnection(client, requestUrl)
let effectiveHeaders = client.headers.override(headers) let effectiveHeaders = client.headers.override(headers)