Skip to content

Releases: ehennestad/http-progressbar-matlab

v2.1.0 - Resumable downloads, multipart uploads, progress and cancel callbacks

Choose a tag to compare

@github-actions github-actions released this 05 Oct 18:15

MATLAB Versions Tested

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 in FILENAME.part when a download fails or is interrupted, and a later call with Resume=true asks the server for the rest only. The entity tag and length of the file are kept in FILENAME.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 raises webprogress:download:FolderTargetNotResumable. Two MATLAB sessions must not resume the same FILENAME: they write the same partial file and corrupt it (#25).
  • webprogress.upload accepts Offset and NumBytes to send one byte range of a file, with its length in Content-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 an Offset at the end of the file, raises webprogress:upload:RangeOutsideFile; NumBytes=0 raises MATLAB:validators:mustBePositive; a file that shrinks during the upload raises webprogress:upload:FileChanged (#26).
  • webprogress.MultipartProgressMonitor(TOTALBYTES) shows one progress display for a file uploaded in several requests. Pass it to each part with webprogress.upload(...,ProgressMonitor=MONITOR); a part the server accepts is added to CompletedBytes, a part that fails is not, and close(monitor) closes the display or prints the completion message. CompletedBytes=N at construction starts a monitor at the bytes a server already accepted, to continue an upload after a cancel (#26, #33).
  • ProgressFcn on webprogress.download, webprogress.upload and both monitor classes is called with a struct of ActionName, TransferredBytes and TotalBytes, at most once per UpdateInterval and 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).
  • CancelRequestedFcn on the same functions and classes is called before a transfer and at most once per UpdateInterval while it runs, and stops the transfer when it returns true. webprogress.download and webprogress.upload then raise webprogress:download:Cancelled or webprogress:upload:Cancelled; upload raises it also when called with outputs. A cancelled download saves no file, and with Resume=true keeps its partial file (#27).
  • DataTimeout=SECONDS on webprogress.download and webprogress.upload sets how long a transfer may receive no data before it stops with webprogress:download:TransferStalled or webprogress:upload:TransferStalled; Inf waits without limit (#31).
  • webprogress.FileTransferProgressMonitor accepts StartBytes, 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, raises TransferStalled, where v2.0.0 waited without limit. Pass DataTimeout=Inf to keep waiting (#31).
  • The Cancel button of the progress dialog raises webprogress:download:Cancelled or webprogress:upload:Cancelled at the next progress report, which a try/catch block can handle. In v2.0.0 it stopped the call the way Ctrl+C does, past every catch block. A cancel acts at the next progress report, so a transfer that has stopped receiving data ends through DataTimeout instead (#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" and CancelRequestedFcn (#27).

Internal

  • AGENTS.md records 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, UploadRangeTest and ProgressCallbackTest are new (#25, #26, #27, #31).
  • captureOutput and listFiles are shared from tests/helpers instead 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, where openedFiles does 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

Choose a tag to compare

@github-actions github-actions released this 21 Sep 15:12

MATLAB Versions Tested

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.download and webprogress.upload accept Filename=NAME, which is shown in the progress title as given and takes precedence over ShowFilename. 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 as folder/data.bin (#23).

Changed

  • webprogress.download raises webprogress:download:RequestFailed with the server's status line when the response status is not a 2xx status. In v1.2.1 downloadFile saved the server's error page at the target path and returned that path (#3).
  • webprogress.download saves 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 from Content-Type, so LICENSE served as text/plain was saved as LICENSE.txt (#14).
  • With a folder as the target, webprogress.download saves the file under the name in the Content-Disposition header, or else under the last segment of the URL path. Only the last component of a Content-Disposition name is used, so a name such as ../outside.txt cannot write outside the folder. A second download into the same folder replaces the file, where it failed with MATLAB:http:CannotOverwriteNoName before (#14).
  • webprogress.toolboxversion returns the version number alone, such as 2.0.0, instead of Version 2.0.0 (#22).
  • The constructor of webprogress.FileTransferProgressMonitor declares its options in an arguments block. It rejects a name that is not an option, such as DisplayMod, which v1.2.1 skipped without notice, and it validates the values. An unambiguous prefix of an option name is accepted, so 'Disp' sets DisplayMode (#8).
  • The FileSizeBytes property of webprogress.FileTransferProgressMonitor can be set only through the constructor, like the other options (#22).

Removed

  • downloadFile and uploadFile no longer exist. Call webprogress.download and webprogress.upload with the same arguments. FileTransferProgressMonitor is now webprogress.FileTransferProgressMonitor (#2).
  • The constructor of webprogress.FileTransferProgressMonitor no 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.download receives the file in a temporary .part file 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.download raises webprogress:download:IncompleteTransfer when the size of the received file differs from the Content-Length of 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 without Content-Length, such as chunked responses, and responses with a Content-Encoding other than identity are not compared (#24).
  • A response with several Content-Length headers of different values raises webprogress:download:InvalidContentLength. A MATLAB release whose HTTP client uses libcurl 8.17.0 or later rejects such a response itself, with MATLAB:webservices:CopyContentToDataStreamError. In both cases no file is saved (#24).
  • webprogress.download raises webprogress:download:FolderNotFound when the folder of the target does not exist, and webprogress:download:NoFilename when 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.upload treats any 2xx status as success. In v1.2.1 uploadFile compared 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 identifier webprogress:upload:RequestFailed and 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.Interval to 1 second, which is the delay before the HTTP stack first calls the monitor, so a 10 MB download that finished sooner printed nothing. Interval is now at most 0.01 seconds and the first update is displayed without waiting for UpdateInterval; 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 shows Estimating remaining time... (#21).
  • When neither the server nor FileSizeBytes gives 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.download shows the last decoded segment of the URL path, so the title of a signed URL no longer includes the query and its signature, and my%20file.bin is shown as my file.bin. webprogress.upload shows the name of the local file instead of the last segment of the upload URL (#6).
  • The progress passed to uiprogressdlg and the waitbar is limited to the range 0 to 1, and NaN becomes 0. A FileSizeBytes smaller than the transfer raised an error from inside the progress monitor. The percentage in the progress message is not limited, so an incorrect FileSizeBytes remains visible (#7).
  • URLs are validated with matlab.net.URI instead of the undocumented matlab.internal.webservices.urlencode. A URL must have an http or https scheme in lowercase and a host, and an invalid URL raises webprogress:validators:InvalidUrl (#9).
  • webprogress.toolboxversion reports the version of the installed toolbox. In v1.2.1 it reported 1.2.0, because the release updated a second Contents.m that the function does not read (#20).

Documentation

  • webprogress.download and webprogress.upload have help text with one syntax paragraph per output and option. It documents the errors raised, the Figure option and the FileSizeBytes option of download, and that upload raises an error only when it is called without outputs (#11).
  • help webprogress lists the functions of the toolbox below the version header, and the README uses the namespaced function names (#20).

Internal

  • The test suite grows from ToolboxTest to 64 tests in six classes. DownloadTargetTest, ProgressDisplayTest and UploadTest run against a local Python HTTP server in tests/fixtures and are skipped when python3 or a Unix shell is unavailable (#12, #14, #24).
  • The toolbox is packaged from src/webprogress instead of src, so anything that ships in the .mltbx has to live under that folder. webprogress.toolboxdir follows the new layout (#20).
  • webprogresstools.installMatBox picks one .mltbx asset from a MatBox release, and the codespell workflow no longer names a .codespellrc that 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 ...
Read more

v1.2.1

Choose a tag to compare

@github-actions github-actions released this 17 Sep 18:31

MATLAB Versions Tested
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