package archive import ( "archive/tar" "compress/gzip" "fmt" "io" "log" "net/http" "os" "time" ) func (this *ArchiveServer) serveDownload(w http.ResponseWriter) { w.Header().Set(`Content-Type`, `application/octet-stream`) w.Header().Set(`Content-Disposition`, `download; filename="chat-archive-`+time.Now().Format("20060102030405")+`.tar.gz"`) w.WriteHeader(200) gzw := gzip.NewWriter(w) defer gzw.Close() t := tar.NewWriter(gzw) defer t.Close() for i, ls := range this.cfg.Logs { slug, _ := this.bestSlugFor(&this.cfg.Logs[i]) limit := ls.LatestDate().Next() // one off the end for ympair := ls.EarliestDate(); !ympair.Equals(limit); ympair = ympair.Next() { fname, err := this.LogFile(&ls, ympair) if err != nil { continue // no log exists for this ym } fi, err := os.Stat(fname) if err != nil { continue } fh, err := os.Open(fname) if err != nil { continue // can't open this log file } tHdr, _ := tar.FileInfoHeader(fi, "") tHdr.Name = fmt.Sprintf(`/%s/%d-%02d.log`, slug, ympair.Year, ympair.Month) t.WriteHeader(tHdr) func() { defer fh.Close() _, err := io.Copy(t, fh) if err != nil { log.Printf("Error while archiving file '%s': %s", fname, err.Error()) return } }() t.Flush() } } }