Hello, I hope you are very well. I have been trying to figure out how I can allow a nim client to restart a download of data from a NextCloud server. I know that the server serves the data in chunks and if I add the code in the nim documentation:
asyncdispatch, httpclient
proc onProgressChanged(total, progress, speed: BiggestInt) {.async.} =
echo("Downloaded ", progress, " of ", total)
echo("Current rate: ", speed div 1000, "kb/s")
proc asyncProc() {.async.} =
var client = newAsyncHttpClient()
client.onProgressChanged = onProgressChanged
discard await client.getContent("http://speedtest-ams2.digitalocean.com/100mb.test")
waitFor asyncProc()
That works fine and I can see the download progress of a 1GB file. But, what I can't do is figure out how to store the data in a file as it's being downloaded. Then, if the connection interrupts I can skip the chunks downloaded and pick-up after the last successful chunk.
As I understand things if I don't discard the result of the getContent I only get to use the content after the file entire file has been read from the server. I thought, maybe I could somehow handle the writing to a file in the callback, but I can't see how to do that.
Does anyone have a suggestion on how to do this? Maybe there's a better approach? Many thanks, adil
Not sure how to do it with the async httpclient, but using the sync version you should be ably to read chunks like this:
import httpclient
import strformat
import streams
var client = newHttpClient()
var response = client.get("https://example.com")
var buffer = newString(32)
while not response.bodyStream.atEnd():
buffer.setLen(32)
let nrecv = response.bodyStream.readDataStr(buffer, 0..31)
buffer.setLen(nrecv)
echo(&"read {nrecv} bytes: {buffer}")
If you want to handle retrying, you should probably read https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests.