Workaround 'defer' issue in httpclient.downloadFile. Refs #3877. (#7101)

This commit is contained in:
Dominik Picheta 2018-01-18 13:08:35 +00:00 • committed by Andreas Rumpf
commit ef19634065

View file

@ -1263,21 +1263,30 @@ proc postContent*(client: HttpClient | AsyncHttpClient, url: string,
else: else:
return await resp.bodyStream.readAll() return await resp.bodyStream.readAll()
proc downloadFile*(client: HttpClient | AsyncHttpClient, proc downloadFile*(client: HttpClient, url: string, filename: string) =
url: string, filename: string): Future[void] {.multisync.} =
## Downloads ``url`` and saves it to ``filename``. ## Downloads ``url`` and saves it to ``filename``.
client.getBody = false client.getBody = false
defer: defer:
client.getBody = true client.getBody = true
let resp = await client.get(url) let resp = client.get(url)
when client is HttpClient:
client.bodyStream = newFileStream(filename, fmWrite) client.bodyStream = newFileStream(filename, fmWrite)
if client.bodyStream.isNil: if client.bodyStream.isNil:
fileError("Unable to open file") fileError("Unable to open file")
parseBody(client, resp.headers, resp.version) parseBody(client, resp.headers, resp.version)
client.bodyStream.close() client.bodyStream.close()
else:
if resp.code.is4xx or resp.code.is5xx:
raise newException(HttpRequestError, resp.status)
proc downloadFile*(client: AsyncHttpClient, url: string,
filename: string): Future[void] =
proc downloadFileEx(client: AsyncHttpClient,
url, filename: string): Future[void] {.async.} =
## Downloads ``url`` and saves it to ``filename``.
client.getBody = false
let resp = await client.get(url)
client.bodyStream = newFutureStream[string]("downloadFile") client.bodyStream = newFutureStream[string]("downloadFile")
var file = openAsync(filename, fmWrite) var file = openAsync(filename, fmWrite)
# Let `parseBody` write response data into client.bodyStream in the # Let `parseBody` write response data into client.bodyStream in the
@ -1290,3 +1299,13 @@ proc downloadFile*(client: HttpClient | AsyncHttpClient,
if resp.code.is4xx or resp.code.is5xx: if resp.code.is4xx or resp.code.is5xx:
raise newException(HttpRequestError, resp.status) raise newException(HttpRequestError, resp.status)
result = newFuture[void]("downloadFile")
try:
result = downloadFileEx(client, url, filename)
except Exception as exc:
result.fail(exc)
finally:
result.addCallback(
proc () = client.getBody = true
)