Created
November 14, 2022 13:33
-
-
Save naartjie/8cdccd800a93f55f8ccbbfc6cff35fe5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#r "nuget: FsHttp, 9.1.2" | |
open FsHttp | |
open System | |
let getSize url = | |
async { | |
let! r = | |
http { | |
HEAD url | |
CacheControl "no-cache" | |
} | |
|> Request.sendAsync | |
return float r.content.Headers.ContentLength.Value | |
} | |
let sizeToRanges (size: float) = | |
let x = Math.Ceiling(size / (float 5)) | |
seq { 1. .. 5. } | |
|> Seq.map (fun n -> x * (n - 1.), (min size (x * n - 1.))) | |
|> Seq.toList | |
let getRange url x1 x2 = | |
async { | |
let! res = | |
http { | |
GET url | |
(* https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests *) | |
header "range" $"bytes={x1}-{x2}" | |
CacheControl "no-cache" | |
} | |
|> Request.sendAsync | |
let! bytes = Response.toBytesAsync res | |
return bytes | |
} | |
let download url dest = | |
let size = getSize url |> Async.RunSynchronously | |
printfn $"url={url} size={size}" | |
let content = | |
sizeToRanges size | |
|> List.map (fun (x1, x2) -> getRange url x1 x2) | |
|> fun content -> Async.Parallel(content, maxDegreeOfParallelism = 5) | |
|> Async.RunSynchronously | |
|> Array.concat | |
IO.File.WriteAllBytes(dest, content) | |
printfn $"got {url}, size={content.Length}" | |
let args = Environment.GetCommandLineArgs() | |
let url, dest = args.[2], args.[3] | |
download url dest |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment