Repository navigation
Releases: ehennestad/http-progressbar-matlab
Release list
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
v2.0.0 - webprogress namespace, errors for failed and truncated downloads, Filename option
downloadFile and uploadFile are now webprogress.download and webprogress.upload, and a download that fails, is interrupted or is cut short raises an error and leaves no file at the target path. Upgrading takes renaming the calls; the arguments are unchanged. See Changed and Removed before upgrading, because a failed download now raises an error where v1.2.1 returned normally.
Added
webprogress.downloadandwebprogress.uploadacceptFilename=NAME, which is shown in the progress title as given and takes precedence overShowFilename. Use it when the last segment of a download URL is an identifier, or when an uploaded object is known by its path in a storage bucket, such asfolder/data.bin(#23).
Changed
webprogress.downloadraiseswebprogress:download:RequestFailedwith the server's status line when the response status is not a 2xx status. In v1.2.1downloadFilesaved the server's error page at the target path and returned that path (#3).webprogress.downloadsaves a file target under the exact name given. In v1.2.1 a target without an extension was given one, from the URL or else fromContent-Type, soLICENSEserved astext/plainwas saved asLICENSE.txt(#14).- With a folder as the target,
webprogress.downloadsaves the file under the name in theContent-Dispositionheader, or else under the last segment of the URL path. Only the last component of aContent-Dispositionname is used, so a name such as../outside.txtcannot write outside the folder. A second download into the same folder replaces the file, where it failed withMATLAB:http:CannotOverwriteNoNamebefore (#14). webprogress.toolboxversionreturns the version number alone, such as2.0.0, instead ofVersion 2.0.0(#22).- The constructor of
webprogress.FileTransferProgressMonitordeclares its options in anargumentsblock. It rejects a name that is not an option, such asDisplayMod, which v1.2.1 skipped without notice, and it validates the values. An unambiguous prefix of an option name is accepted, so'Disp'setsDisplayMode(#8). - The
FileSizeBytesproperty ofwebprogress.FileTransferProgressMonitorcan be set only through the constructor, like the other options (#22).
Removed
downloadFileanduploadFileno longer exist. Callwebprogress.downloadandwebprogress.uploadwith the same arguments.FileTransferProgressMonitoris nowwebprogress.FileTransferProgressMonitor(#2).- The constructor of
webprogress.FileTransferProgressMonitorno longer accepts a scalar struct of options. Pass name-value arguments instead (#8).
Fixed
- A failed or interrupted download leaves an existing file at the target path unchanged.
webprogress.downloadreceives the file in a temporary.partfile in the target folder and moves it to the target only after a successful response. The temporary file is deleted when the function exits early, including by an error or Ctrl+C (#14). webprogress.downloadraiseswebprogress:download:IncompleteTransferwhen the size of the received file differs from theContent-Lengthof the response. The MATLAB HTTP client returns without an error when the server closes the connection early, so a dropped connection saved a truncated file under the final name. Responses withoutContent-Length, such as chunked responses, and responses with aContent-Encodingother thanidentityare not compared (#24).- A response with several
Content-Lengthheaders of different values raiseswebprogress:download:InvalidContentLength. A MATLAB release whose HTTP client uses libcurl 8.17.0 or later rejects such a response itself, withMATLAB:webservices:CopyContentToDataStreamError. In both cases no file is saved (#24). webprogress.downloadraiseswebprogress:download:FolderNotFoundwhen the folder of the target does not exist, andwebprogress:download:NoFilenamewhen a folder target gets no file name from the response or the URL. A response with an empty body saves an empty file (#14).webprogress.uploadtreats any 2xx status as success. In v1.2.1uploadFilecompared the status with 200 only, so an upload acknowledged with 201 Created or 204 No Content was reported as failed. The error raised for an unsuccessful status has the identifierwebprogress:upload:RequestFailedand names the server's status line (#4).- Progress is shown for transfers shorter than one second, including the completion message. v1.2.1 set
ProgressMonitor.Intervalto 1 second, which is the delay before the HTTP stack first calls the monitor, so a 10 MB download that finished sooner printed nothing.Intervalis now at most 0.01 seconds and the first update is displayed without waiting forUpdateInterval; later updates are throttled as before (#21, #22). - The remaining time is shown only when the transferred fraction supports an estimate. A transfer that had not received its first bytes after ten seconds reported
Estimated time remaining: Inf hours; it now showsEstimating remaining time...(#21). - When neither the server nor
FileSizeBytesgives the size of the transfer, the status line and the completion message report the transferred size alone (#22). - Cancelling a transfer closes the progress display and keeps it closed. The byte counts that the HTTP stack reports before it acts on the cancellation opened a new dialog or waitbar (#22).
- A finished upload is described as an upload. When the server's reply had no body, the completion message read
Downloaded 0 MB/0 MB (Inf%)(#5). - With
ShowFilename,webprogress.downloadshows the last decoded segment of the URL path, so the title of a signed URL no longer includes the query and its signature, andmy%20file.binis shown asmy file.bin.webprogress.uploadshows the name of the local file instead of the last segment of the upload URL (#6). - The progress passed to
uiprogressdlgand the waitbar is limited to the range 0 to 1, and NaN becomes 0. AFileSizeBytessmaller than the transfer raised an error from inside the progress monitor. The percentage in the progress message is not limited, so an incorrectFileSizeBytesremains visible (#7). - URLs are validated with
matlab.net.URIinstead of the undocumentedmatlab.internal.webservices.urlencode. A URL must have anhttporhttpsscheme in lowercase and a host, and an invalid URL raiseswebprogress:validators:InvalidUrl(#9). webprogress.toolboxversionreports the version of the installed toolbox. In v1.2.1 it reported 1.2.0, because the release updated a secondContents.mthat the function does not read (#20).
Documentation
webprogress.downloadandwebprogress.uploadhave help text with one syntax paragraph per output and option. It documents the errors raised, theFigureoption and theFileSizeBytesoption ofdownload, and thatuploadraises an error only when it is called without outputs (#11).help webprogresslists the functions of the toolbox below the version header, and the README uses the namespaced function names (#20).
Internal
- The test suite grows from
ToolboxTestto 64 tests in six classes.DownloadTargetTest,ProgressDisplayTestandUploadTestrun against a local Python HTTP server intests/fixturesand are skipped whenpython3or a Unix shell is unavailable (#12, #14, #24). - The toolbox is packaged from
src/webprogressinstead ofsrc, so anything that ships in the.mltbxhas to live under that folder.webprogress.toolboxdirfollows the new layout (#20). webprogresstools.installMatBoxpicks one.mltbxasset from a MatBox release, and the codespell workflow no longer names a.codespellrcthat the repository does not have (#22).- The test workflow caches the MATLAB installation and uploads coverage to Codecov (552eea7).
All merged pull requests
What's Changed
- refactor!: move ...
v1.2.1
This is the first release of this toolbox on GitHub (it was previously only released via FileExchange). Changes from v1.2.0 includes changes to the example and minor fixes in uploadFile.
What's Changed
- chore: import existing source into the toolbox layout by @ehennestad in #1
- fix: make the progress dialog demo the only example and the guide by @ehennestad in #16
- docs: fix the progress demo live script and download an OVHcloud test file by @ehennestad in #17
Full Changelog: https://github.com/ehennestad/http-progressbar-matlab/commits/v1.2.1