Skip to content

Instantly share code, notes, and snippets.

@nl5887
Last active August 27, 2020 19:20
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save nl5887/f88ca64b67f7dce3690c to your computer and use it in GitHub Desktop.
Save nl5887/f88ca64b67f7dce3690c to your computer and use it in GitHub Desktop.
Dynamically returns a zip file consisting of multiple Amazon S3 objects
// download zipfile
func ZipHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
token := vars["token"]
db, err := sql.Open("mysql", config.DSN)
if err != nil {
panic(err.Error()) // Just for example purpose. You should use proper error handling instead of panic
}
defer db.Close()
var d delivery
{
stmt, err := db.Prepare("SELECT deliveryid FROM deliveries WHERE (token = ?)")
if err != nil {
log.Fatal(err)
}
if err := stmt.QueryRow(token).Scan(&d.deliveryid); err != nil {
// log.Fatal(err)
http.NotFound(w, r)
return
}
stmt.Close()
}
filename := fmt.Sprintf("%s.zip", token)
w.Header().Set("Content-Type", "application/zip")
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename))
{
zw := zip.NewWriter(w)
auth := aws.Auth{config.AWS_ACCESS_KEY, config.AWS_SECRET_KEY}
// make region variable and save in database
conn := s3.New(auth, aws.Regions["eu-west-1"])
b := conn.Bucket(config.BUCKET)
stmt, err := db.Prepare("SELECT attachmentid, url, filename, size, filetype FROM attachments WHERE (token = ?)")
rows, err := stmt.Query(token)
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var a attachment
if err := rows.Scan(&a.attachmentid, &a.url, &a.filename, &a.size, &a.filetype); err != nil {
log.Fatal(err)
continue
}
fi, err := b.GetReader(a.url)
if err != nil {
// log.Info(err)
continue
}
header := &zip.FileHeader{
Name: a.filename,
Method: zip.Store,
ModifiedTime: uint16(time.Now().UnixNano()),
ModifiedDate: uint16(time.Now().UnixNano()),
}
fw, err := zw.CreateHeader(header)
if err != nil {
log.Fatal(err)
}
if _, err = io.Copy(fw, fi); err != nil {
log.Fatal(err)
}
if err = fi.Close(); err != nil {
log.Fatal(err)
}
}
stmt.Close()
if err := zw.Close(); err != nil {
log.Fatal(err)
}
}
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment