-
Notifications
You must be signed in to change notification settings - Fork 40
/
zip.go
71 lines (61 loc) · 1.43 KB
/
zip.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package main
import (
"archive/zip"
"fmt"
"log"
"net/http"
"strings"
)
func archiveFilename(path, ext string) string {
parts := strings.Split(path, "/")
filename := "cbfs-archive." + ext
for len(parts) > 0 {
if p := parts[len(parts)-1]; p != "" {
filename = p + "." + ext
break
}
parts = parts[:len(parts)-1]
}
return filename
}
func doZipDocs(w http.ResponseWriter, req *http.Request,
path string) {
quit := make(chan bool)
defer close(quit)
ch := make(chan *namedFile)
cherr := make(chan error)
go pathGenerator(path, ch, cherr, quit)
go logErrors("zip", cherr)
w.Header().Set("Content-Disposition",
fmt.Sprintf("attachment; filename=%q", archiveFilename(path, "zip")))
w.Header().Set("Content-Type", "application/zip")
w.WriteHeader(200)
zw := zip.NewWriter(w)
for nf := range ch {
if nf.err != nil {
log.Printf("Error on %v: %v", nf.name, nf.err)
continue
}
fh := zip.FileHeader{
Name: nf.name,
Method: zip.Deflate,
UncompressedSize: uint32(nf.meta.Length),
Comment: nf.meta.OID,
}
fh.SetModTime(nf.meta.Modified)
zf, err := zw.CreateHeader(&fh)
if err != nil {
log.Printf("Error making zip file: %v", err)
// Client will get a broken zip file
return
}
err = copyBlob(zf, nf.meta.OID)
if err != nil {
log.Printf("Error copying blob for %v: %v",
nf.name, err)
// Client will get a broken zip file
return
}
}
zw.Close()
}