Repository navigation
v2.1.0 - Resumable downloads, multipart uploads, progress and cancel callbacks
webprogress.download can continue an interrupted download, and webprogress.upload can send one part of a file and show a multipart upload in one display. Both can report progress to a function you supply and stop when it asks them to. Existing code keeps working, with two changes to read under Changed: a transfer that receives no data for 60 seconds now stops with an error, and the Cancel button of the progress dialog raises an error that a try/catch block can handle.
Added
webprogress.download(...,Resume=true)keeps the part of the file received so far inFILENAME.partwhen a download fails or is interrupted, and a later call withResume=trueasks the server for the rest only. The entity tag and length of the file are kept inFILENAME.part.json, so the URL may change between calls, as a presigned URL does. When the file has changed on the server, the server cannot send a range, or it gives the file no strong ETag, the download starts from the beginning. A folder target raiseswebprogress:download:FolderTargetNotResumable. Two MATLAB sessions must not resume the sameFILENAME: they write the same partial file and corrupt it (#25).webprogress.uploadacceptsOffsetandNumBytesto send one byte range of a file, with its length inContent-Length. Every request reads the range from its start, so a part can be sent again after a failure or a redirect. A range outside the file, including anOffsetat the end of the file, raiseswebprogress:upload:RangeOutsideFile;NumBytes=0raisesMATLAB:validators:mustBePositive; a file that shrinks during the upload raiseswebprogress:upload:FileChanged(#26).webprogress.MultipartProgressMonitor(TOTALBYTES)shows one progress display for a file uploaded in several requests. Pass it to each part withwebprogress.upload(...,ProgressMonitor=MONITOR); a part the server accepts is added toCompletedBytes, a part that fails is not, andclose(monitor)closes the display or prints the completion message.CompletedBytes=Nat construction starts a monitor at the bytes a server already accepted, to continue an upload after a cancel (#26, #33).ProgressFcnonwebprogress.download,webprogress.uploadand both monitor classes is called with a struct ofActionName,TransferredBytesandTotalBytes, at most once perUpdateIntervaland once more when the transfer is done.DisplayMode="None"turns the built-in display off, so the progress can be shown in an app of your own (#27).CancelRequestedFcnon the same functions and classes is called before a transfer and at most once perUpdateIntervalwhile it runs, and stops the transfer when it returns true.webprogress.downloadandwebprogress.uploadthen raisewebprogress:download:Cancelledorwebprogress:upload:Cancelled;uploadraises it also when called with outputs. A cancelled download saves no file, and withResume=truekeeps its partial file (#27).DataTimeout=SECONDSonwebprogress.downloadandwebprogress.uploadsets how long a transfer may receive no data before it stops withwebprogress:download:TransferStalledorwebprogress:upload:TransferStalled;Infwaits without limit (#31).webprogress.FileTransferProgressMonitoracceptsStartBytes, the bytes of the file transferred before this transfer, which count toward the progress but not toward the remaining-time estimate (#25).
Changed
- A transfer that receives no data for 60 seconds, the default
DataTimeout, raisesTransferStalled, where v2.0.0 waited without limit. PassDataTimeout=Infto keep waiting (#31). - The Cancel button of the progress dialog raises
webprogress:download:Cancelledorwebprogress:upload:Cancelledat the next progress report, which atry/catchblock can handle. In v2.0.0 it stopped the call the way Ctrl+C does, past everycatchblock. A cancel acts at the next progress report, so a transfer that has stopped receiving data ends throughDataTimeoutinstead (#27).
Fixed
- An upload whose server replies with a body, as Dropbox does with JSON, is described as an upload to the end. In v2.0.0 the display switched to the reply, and the completion message described a download of 0 MB. The reply's bytes no longer replace the uploaded byte count in the display, the completion message or the reports to
ProgressFcn(#27).
Documentation
- The README shows how to drive a display of your own with
ProgressFcn,DisplayMode="None"andCancelRequestedFcn(#27).
Internal
AGENTS.mdrecords that the resume, multipart, callback and timeout layers were reviewed for structure, naming and tests rather than for HTTP semantics, and lists the behaviour of the MATLAB HTTP stack that was established by probing it (#33).- The test suite grows to 154 tests in nine classes. The local test server honours byte ranges and ETags, can truncate, delay, redirect and stall a transfer, echoes uploaded bodies, and lists the requests it received.
DownloadResumeTest,UploadRangeTestandProgressCallbackTestare new (#25, #26, #27, #31). captureOutputandlistFilesare shared fromtests/helpersinstead of copied into each test class (#30).- The short-download progress tests get a body that lasts longer than the monitor's first-call interval, so they no longer fail when the body arrives within 10 ms (#29).
- A test lists open files with
fopen('all')before R2024a, whereopenedFilesdoes not exist (#35).
All merged pull requests
What's Changed
- test: delay the body in the short download progress tests by @ehennestad in #29
- feat: resume an interrupted download with Resume=true by @ehennestad in #25
- feat: upload a byte range of a file and show parts in one display by @ehennestad in #26
- feat: report progress to a callback and cancel a transfer on request by @ehennestad in #27
- test: share captureOutput and listFiles between the test classes by @ehennestad in #30
- feat: stop a transfer that receives no data for DataTimeout seconds by @ehennestad in #31
- feat: start a MultipartProgressMonitor at the bytes already accepted by @ehennestad in #33
- test: list open files with fopen('all') before R2024a by @ehennestad in #35
Full Changelog: v2.0.0...v2.1.0