https://github.com/vearutop/httpzip
Serve/download multiple files over HTTP as ZIP in Go
https://github.com/vearutop/httpzip
golang http-server zip
Last synced: 11 months ago
JSON representation
Serve/download multiple files over HTTP as ZIP in Go
- Host: GitHub
- URL: https://github.com/vearutop/httpzip
- Owner: vearutop
- License: mit
- Created: 2024-12-20T16:05:34.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2025-07-25T11:56:40.000Z (11 months ago)
- Last Synced: 2025-07-25T17:57:46.452Z (11 months ago)
- Topics: golang, http-server, zip
- Language: Go
- Homepage:
- Size: 20.5 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# httpzip
[](https://github.com/vearutop/httpzip/actions?query=branch%3Amaster+workflow%3Atest-unit)
[](https://codecov.io/gh/vearutop/httpzip)
[](https://pkg.go.dev/github.com/vearutop/httpzip)
[](https://wakatime.com/badge/github/vearutop/httpzip)


Serve multiple files in uncompressed ZIP stream (no temporary archive file) with progress (`Content-Length` header) status.
```go
h := httpzip.NewHandler("archive")
h.OnError = func(err error) {
log.Println(err)
}
c := "hello world"
for i := 0; i < 10; i++ {
if err := h.AddFile(httpzip.FileSource{
Path: fmt.Sprintf("file_%d.txt", i),
Modified: time.Now(),
Size: int64(len(c)),
Data: func(w io.Writer) error {
_, err := w.Write([]byte(c)) // Mimicking actual file source.
return err
},
}); err != nil {
log.Println(err)
}
}
h.ServeHTTP(rw, nil)
```
Extract ZIP file directly (no temporary archive file) from a URL.
```go
resp, err := http.Get("https://www.example.com/archive.zip")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
zr := httpzip.NewStreamReader(resp.Body)
for {
e, err := zr.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatalf("failed to find next file in zip: %s", err)
}
log.Println("file path:", e.Name)
if !e.IsDir() {
rc, err := e.Open()
if err != nil {
log.Fatalf("unable to open zip file entry: %s", err)
}
w, err := io.Copy(io.Discard, rc)
if err != nil {
log.Fatalf("unable to stream zip file: %s (%d)", err, w)
}
log.Println("file length:", w)
if err := rc.Close(); err != nil {
log.Fatalf("failed to close zip file entry: %s", err)
}
}
}
```