ZipStreamer is a golang microservice for streaming zip files from a series of web links, on the fly. For example, if you have 200 files on S3, and you want to download a zip file of them, you can do so in 1 request to this server.
Highlights include:
zip_streamer.go
)Each HTTP endpoint requires a JSON description of the desired zip file. It includes a root object with the following structure:
suggestedFilename
[Optional, string]: The filename to suggest in the "Save As" UI in browsers. Defaults to archive.zip
if not provided or invalid. Limited to US-ASCII.files
[Required, array]: an array descibing the files to include in the zip file. Each array entry required 2 properties:
url
[Required, string]: the public URL of the file to include in the zip. Zipstreamer will fetch this via a GET request. The file must be publically accessible via this URL; if you're files are private, most file hosts provide query string authentication options which work well with Zipstreamer (example AWS S3 Docs).zipPath
[Required, string]: the path and filename where this entry should appear in the resulting zip file. This is a relative path to the root of the zip file.Example JSON description with 2 files:
{
"suggestedFilename": "tps_reports.zip",
"files": [
{
"url":"https://server.com/image1.jpg",
"zipPath":"image1.jpg"
},
{
"url":"https://server.com/image2.jpg",
"zipPath":"in-a-sub-folder/image2.jpg"
}
]
}
POST /download
This endpoint takes a http POST body containing the JSON zip file descriptor, and returns a zip file.
GET /download
This endpoint fetches a JSON zip file descriptor hosted on another server, and returns a zip file. This is useful over the POST /download
endpoint for a few use cases:
zsid
parameter)POST /create_download_link
for a client side alternitive to achieve this.This endpoint requires one of two query parameters describing where to find the JSON zip file descriptor:
zsurl
: the full URL to the JSON file describing the zip. Example: /download?zsurl=https://yourserver.com/path_to_descriptors/82a1b54cd20ab44a916bd76a5
zsid
: must be used with the ZS_LISTFILE_URL_PREFIX
environment variable. The JSON file will be fetched from ZS_LISTFILE_URL_PREFIX + zsid
. This allows you to hide the full URL path from clients, revealing only the end of the URL. Example: ZS_LISTFILE_URL_PREFIX = "https://yoursever.com/path_to_descriptors/"
and /download?zsid=82a1b54cd20ab44a916bd76a5
POST /create_download_link
This endpoint takes a http POST body containing the JSON zip file descriptor, stores it in a local cache, and returns a link ID which allows the caller to fetch the zip file via an additional call to GET /download_link/{link_id}
.
This is useful for if you want to trigger a browser "Save File" UI, which isn't shown for POST requests. See GET /download
for a server side alternative to achieve this.
Important:
Here is an example response body containing the link ID. See docs for GET /download_link/{link_id}
below for how to fetch this zip file:
{
"status":"ok",
"link_id":"b4ecfdb7-e0fa-4aca-ad87-cb2e4245c8dd"
}
Example usage: see GET /download_link/{link_id}
documentation below.
GET /download_link/{link_id}
Call this endpoint with a link_id
generated with /create_download_link
to download that zip file.
Be sure to enable session affinity if you're using multiple servers and using /create_download_link
.
Cloud Run is ideal serverless environment for ZipStreamer, as it routes many requests to a single container instance. ZipStreamer is designed to handle many concurrent requests, and will be cheaper to run on this serverless architecture than a instance-per-request architecture like AWS Lamba or Google Cloud Functions.
Important
ZS_URL_PREFIX
is blank in the Cloud Run console./create_download_link
. Cloud Run may scale up to multiple containers automatically.This repo contains an dockerfile, and an image is published on Github Packages.
To build your own image, clone the repo and run:
docker build --tag docker-zipstreamer .
# Start on port 8080
docker run --env PORT=8080 -p 8080:8080 docker-zipstreamer
Official packages are published on Github packages. To pull latest stable release:
docker pull ghcr.io/scosman/packages/zipstreamer:stable
# Start on port 8080
docker run --env PORT=8080 -p 8080:8080 ghcr.io/scosman/packages/zipstreamer:stable
Note: stable
pulls the latest github release. Use ghcr.io/scosman/packages/zipstreamer:latest
for top of tree.
These environment variables can be used to configure the server:
PORT
- Defaults to 4008. Sets which port the HTTP server binds to.ZS_URL_PREFIX
- If set, the server will verify the url
property of the files in the JSON zip file descriptors start with this prefix. Useful to preventing others from using your server to serve their files.ZS_COMPRESSION
- Defaults to no compression. It's not universally known, but zip files can be uncompressed, and used only to combining many files into one file. Set to DEFLATE
to use zip deflate compression. WARNING - enabling compression uses CPU, and will reduce throughput of server. Note: for files with internal compression (JPEGs, MP4s, etc), zip DEFLATE compression will often increase the total zip file size.
ZS_LISTFILE_URL_PREFIX
- See documentation for GET /download
I was mentoring at a "Teens Learning Code" class, but we had too many mentors, so I had some downtime.
Zipper portion of logo by Kokota from Noun Project (Creative Commons CCBY)