Zsync enables partial updates of local files, think client-side rsync over HTTP. The only server-side requirement is support for HTTP range requests.
zsync3 is an opinionated fork of the original zsync.
The main differences are
- removal of compression awareness
- zsync3 uses the host's
curlto download the ranges, which means it adds support for https. - Bazel build system and Bazel rules support
This repository contains
zsync, a program to update a local file using ranged downloadszsyncmake, a program to create .zsync fileszsyncfile, a Bazel rule to generate a .zsync file for a given filezsyncranges, a program to tell which ranges of a file need updating
Compared to the original zsync, zsync3:
- Does not support any compression. It will not look inside .gz files. In fact zsync3 does not depend on zlib anymore.
- Uses
curlsubprocess calls under the hood to download the http ranges. This means it supports https, which the original zsync did not support.
Flag changes:
- No
-Vto print the version (to improve Bazel caching) - No
-swhich was a synomym for-q(quiet). - No
-Aflag orhttp_proxyenv var to supply http username/password. (See note onZSYNC_CURLbelow)
zsync3 uses the ZSYNC_CURL environment variable to specify the curl command to use (default: curl).
This can be used to specify a proxy or other curl options:
ZSYNC_CURL='curl --user "$USER:$PASS"' zsync3 http://example.com/file.zsyncThe value of the ZSYNC_CURL environment variable is passed as is to sh -c in the curl subprocess popen so this variable expansion is possible.
The curl options --fail-with-body, --silent, --show-error, --location, --netrc are always added to the curl command.
Compared to the original zsyncmake, zsync3:
- Does not support any compression. It will not look inside .gz files. In fact zsync3 does not depend on zlib anymore.
- Behaves like original zsync zsyncmake with the flags
-e-Zset. - The
-e(do_exact),-C(do_recompress),-U(URL to decompressed content),-z(do_compress),-Z(no_look_inside) flags are removed. - No
-Vto print the version (to improve Bazel caching) - A new
-Mflag to disable the MTime header being added to the zsync file (to enable reproducible builds).
zsyncfile is a Bazel rule to generate a .zsync file for a given file.
Use it like this:
load("@rules_appimage//appimage:appimage.bzl", "appimage") # example
load("@zsync3//:zsyncfile.bzl", "zsyncfile")
# example
appimage(
name = "program.appimage",
binary = ":program",
)
zsyncfile(
name = "program.appimage.zsync",
file = ":program.appimage",
)❯ bazel build //path/to/program:program.appimage.zsync
❯ head -n7 bazel-bin/path/to/program/program.appimage.zsync
zsync: 0.6.2
Filename: path/to/program/program.appimage.zsync
Blocksize: 2048
Length: 123456
Hash-Lengths: 1,2,4
URL: program.appimage
SHA-1: da39a3ee5e6b4b0d3255bfef95601890afd80709The rules supports optional attributes to set the URL, Filename, and Blocksize.
zsyncranges is a program to tell which ranges of a file need updating without downloading anything.
Compared to zsync, it only supports exactly one source (seed) file and requries the zsyncfile to be a local file.
zsyncranges prints a json list of the start and end byte offsets of the ranges that need updating in the source (seed) file.
❯ bazel run @zsync3//:zsyncranges -- "$(pwd)/file.zsync" "$(pwd)/file"
{"length":1057,"reuse":[[0,0,168],[184,184,264],[456,456,104],[576,576,224],[808,808,249]],"download":[[168,183],[448,455],[560,575],[800,807]]}(The need for $(pwd) is a Bazel thing.)
The intended use case of zsyncranges is integration with a download manager that supports ranged downloads.
Is an example of how to use zsyncranges to download the ranges that need updating.
Please don't use this directly: this is an example, not production level code.
It could be written much more elegantly using the requests library.
❯ bazel build @zsync3//:zsyncranges
❯ rm -f outfile
❯ PATH="$PATH:bazel-bin" ./zsyncdownload.py https://example.com/file.zsync infile outfile
❯ curl -fsSL https://example.com/file.zsync | grep -a SHA-1
SHA-1: 4128828a8827665e80a648b3db036988fe479efc
❯ sha1sum outfile
4128828a8827665e80a648b3db036988fe479efc outfileZsync's combination of popularity and abandonment has led to a number of forks and reimplementations.
| Repository | Language | Maintained | Notes |
|---|---|---|---|
| https://github.com/cph6/zsync | C | 💀 | Available via most package managers, just apt install zsync |
| https://github.com/lalten/zsync <-- you're here | C | ✅ | No compression support. Using curl http client, or none at all (just print ranges). Bazel integration |
| https://github.com/sisong/hsynz | C++ | ✅ | Supports zstd, stronger checksums, directories. Using forked minihttp http client lib |
| https://github.com/AppImageCommunity/zsync2 | C++ | ✅ | C++ wrapper for zsync. Using libcpr http client lib |
| https://github.com/probonopd/zsync-curl | C | 💀 | Mostly original zsync. Using libcurl http client lib |
| https://github.com/AppImageCommunity/zsync3 | C++ | 💀 | |
| https://github.com/salesforce/zsync4j | Java | 💀 | |
| https://github.com/rokups/zinc/ | C++ | 💀 | |
| https://github.com/AppImageCrafters/libzsync-go | Go | 🤷 | |
| https://github.com/Redundancy/go-sync | Go | 💀 | |
| https://github.com/Jsmuk/zsyncnet | .Net | 💀 | |
| https://github.com/disenone/zsync | Python 2 | 💀 | |
| https://github.com/kayahr/zsync | Node.js | 🤷 | |
| https://github.com/myml/msync | Go | 💀 | |
| https://github.com/systemd/casync | C | 💀 | Lots of alternatives mentioned in systemd/casync#259 |