diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-10-06 23:02:51 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-10-08 02:03:05 +0200 |
| commit | 00dd37604d50cbf3fb27ec0631b4d4b6d2ee893a (patch) | |
| tree | 81f9546b168078aa9bf54d4298aa76e99bb229af /page.c | |
| parent | 4ab3ee681607f0cc75cf56e4fcbeae85594bb630 (diff) | |
| download | slcl-00dd37604d50cbf3fb27ec0631b4d4b6d2ee893a.tar.gz | |
Implement directory download as ZIP
Thanks to the fdzipstream library [1] and zlib [2], it is possible to
generate ZIP files on-the-fly, therefore requiring no extra disk space
usage and only a small amount of memory.
Unfortunately, as of the time of this writing fdzipstream is not
packaged by any distributions yet [3], so it had to be imported as a git
submodule as a workaround.
While libarchive [4] could be an interesting alternative, writing ZIP
files is only supported by very recent versions (>= 3.8.0), which are
still not packaged by many distributions [5], either.
Moreover, libarchive is a package with several dependencies other than
zlib and is significantly larger compared to fdzipstreams, so
fdzipstreams was ultimately considered a better fit for this purpose.
[1]: https://github.com/CTrabant/fdzipstream.git
[2]: http://zlib.net/
[3]: https://repology.org/projects/?search=fdzipstream
[4]: https://www.libarchive.org/
[5]: https://repology.org/project/libarchive/versions
Diffstat (limited to 'page.c')
| -rw-r--r-- | page.c | 26 |
1 files changed, 25 insertions, 1 deletions
@@ -1,6 +1,7 @@ #define _POSIX_C_SOURCE 200809L #include "page.h" +#include "zip.h" #include <libweb/html.h> #include <libweb/http.h> #include <dynstr.h> @@ -1812,6 +1813,21 @@ static bool preview(const struct page_resource *const pr) return false; } +static bool download(const struct page_resource *const pr) +{ + for (size_t i = 0; i < pr->n_args; i++) + { + const struct http_arg *const a = &pr->args[i]; + + if (!strcmp(a->key, "download") + && (!strcmp(a->value, "1") + || !strcasecmp(a->value, "true"))) + return true; + } + + return false; +} + int page_resource(const struct page_resource *const pr) { int ret = -1; @@ -1840,7 +1856,15 @@ int page_resource(const struct page_resource *const pr) if (S_ISDIR(m)) { - if ((ret = list_dir(pr))) + if (download(pr)) + { + if ((ret = zip(pr->res, pr->r))) + { + fprintf(stderr, "%s: zip_dir failed\n", __func__); + goto end; + } + } + else if ((ret = list_dir(pr))) { if (ret < 0) { |
