I have an application where users can bulk download images. The client makes a post request with some file ids, the server fetches the filenames and then loops over the filenames, fetching them and writing to zip.
The zipping itself is fine (verified by checking an actual file with os.Create and inspecting it), but I am also trying to avoid saving the resulting zip file and instead directly streaming it to the browser as a response by using io.Copy.
func (c *controller) GetZipped(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
...
files, err := services.FetchImageFileNames(imageIds, id, imgC.db)
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
zipName := time.Now().Format("2006-01-02") + ".zip"
w.Header().Add("Content-Disposition", "attachment; filename=\""+zipName+"\"")
w.Header().Add("Content-Type", "application/zip")
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
zipWriter := zip.NewWriter(w)
zipWriter.Flush()
// Loop over files, fetch the image and add to zip
for _, file := range files {
resp, err := http.Get(c.rcUrl + file)
if err != nil {
continue
}
defer resp.Body.Close()
h := &zip.FileHeader{Name: file, Method: zip.Deflate}
f, err := zipWriter.CreateHeader(h)
if err != nil {
continue
}
io.Copy(f, resp.Body)
resp.Body.Close()
}
zipWriter.Close()
}
In Chrome Dev Tools, I see that the response for this request is receiving data as it streams down, but the files is not downloaded and saved anywhere.
I'd like to avoid saving the zip file and just directly stream the file down, so we can avoid having to do any clean up.
Is this an issue with the browser not recognising the Content Disposition? I've also tried various Content-Type (octet stream etc.) but still no luck.
I was using this as a guide: https://engineroom.teamwork.com/how-to-securely-provide-a-zip-download-of-a-s3-file-bundle/
Any help is much appreciated!