func makezipfile(w io.Writer, contents zdata) { const dirname = "test/" z := zip.NewWriter(w) for k, v := range contents { header := zip.FileHeader{ Name: dirname + k, Method: zip.Store, } header.SetModTime(time.Now()) out, _ := z.CreateHeader(&header) // this should check the number of bytes written, and loop out.Write([]byte(v)) } z.Close() }
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() }
func (zwp *ZipWriterPool) GetWriter(fileIndex int64) (io.WriteCloser, error) { file := zwp.container.Files[fileIndex] fh := zip.FileHeader{ Name: file.Path, UncompressedSize64: uint64(file.Size), Method: zip.Deflate, } fh.SetMode(os.FileMode(file.Mode)) fh.SetModTime(time.Now()) w, err := zwp.zw.CreateHeader(&fh) if err != nil { return nil, errors.Wrap(err, 1) } return &nopWriteCloser{w}, nil }
// create is for internal use. It allows non-payload files to be written. func (w *Writer) create(name string) (io.Writer, error) { // save checksums in case there is an active writer _ = w.Checksum() ck := new(Checksum) w.t.manifest[name] = ck w.checksum = ck header := zip.FileHeader{ Name: w.t.dirname + name, Method: zip.Store, } header.SetModTime(time.Now()) out, err := w.z.CreateHeader(&header) w.hw = util.NewHashWriter(out) return w.hw, err }
func CompressZip(archiveWriter io.Writer, container *tlc.Container, pool wsync.Pool, consumer *state.Consumer) (*archiver.CompressResult, error) { var err error var uncompressedSize int64 var compressedSize int64 archiveCounter := counter.NewWriter(archiveWriter) zipWriter := zip.NewWriter(archiveCounter) defer zipWriter.Close() defer func() { if zipWriter != nil { if zErr := zipWriter.Close(); err == nil && zErr != nil { err = errors.Wrap(zErr, 1) } } }() for _, dir := range container.Dirs { fh := zip.FileHeader{ Name: dir.Path + "/", } fh.SetMode(os.FileMode(dir.Mode)) fh.SetModTime(time.Now()) _, hErr := zipWriter.CreateHeader(&fh) if hErr != nil { return nil, errors.Wrap(hErr, 1) } } for fileIndex, file := range container.Files { fh := zip.FileHeader{ Name: file.Path, UncompressedSize64: uint64(file.Size), Method: zip.Deflate, } fh.SetMode(os.FileMode(file.Mode)) fh.SetModTime(time.Now()) entryWriter, eErr := zipWriter.CreateHeader(&fh) if eErr != nil { return nil, errors.Wrap(eErr, 1) } entryReader, eErr := pool.GetReader(int64(fileIndex)) if eErr != nil { return nil, errors.Wrap(eErr, 1) } copiedBytes, eErr := io.Copy(entryWriter, entryReader) if eErr != nil { return nil, errors.Wrap(eErr, 1) } uncompressedSize += copiedBytes } for _, symlink := range container.Symlinks { fh := zip.FileHeader{ Name: symlink.Path, } fh.SetMode(os.FileMode(symlink.Mode)) entryWriter, eErr := zipWriter.CreateHeader(&fh) if eErr != nil { return nil, errors.Wrap(eErr, 1) } entryWriter.Write([]byte(symlink.Dest)) } err = zipWriter.Close() if err != nil { return nil, errors.Wrap(err, 1) } zipWriter = nil compressedSize = archiveCounter.Count() return &archiver.CompressResult{ UncompressedSize: uncompressedSize, CompressedSize: compressedSize, }, nil }