Search code examples
httpgozip

How do I serve files as a zip?


I'm having a problem serving files for download over HTTP. With my current code, I can download one file easily.

    data, err := ioutil.ReadFile("TEST.docx")
    if err != nil {
        fmt.Println(err)
    }

    log.Fatal(http.ListenAndServe(":3001", http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
        rw.Header().Set("Content-Disposition", "attachment; filename=test.docx")
        http.ServeContent(rw, r, "test.docx", time.Now(), bytes.NewReader(data))
    })))

But I want to be able to download multiple files with one request. Something like this:

    data, err := ioutil.ReadFile("test.docx")
    if err != nil {
        fmt.Println(err)
    }

    data2, err := ioutil.ReadFile("test2.docx")
    if err != nil {
        fmt.Println(err)
    }

    log.Fatal(http.ListenAndServe(":3001", http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
        writer := zip.NewWriter(rw)
        create, _ := writer.Create("test.zip")
        _, _ = create.Write(data)
        _, _ = create.Write(data2)
        rw.Header().Set("Content-Disposition", "attachment; filename=test.zip")

        http.ServeContent(rw, r, "test.zip", time.Now(), /*What am I going to put here?*/)

How can I download these files as a zip? What am I doing wrong?


Solution

  • I misunderstood some of the concepts in my code but I fixed it. Now it works. This is the working code:

        data, err := ioutil.ReadFile("test.docx")
        if err != nil {
            fmt.Println(err)
        }
    
        data2, err := ioutil.ReadFile("test2.docx")
        if err != nil {
            fmt.Println(err)
        }
    
        log.Fatal(http.ListenAndServe(":3001", http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
            buf := new(bytes.Buffer)
            writer := zip.NewWriter(buf)
    
            test, _ := writer.Create("test.docx")
            _, _ = test.Write(data)
            test2, _ := writer.Create("test2.docx")
            _, _ = test2.Write(data2)
            rw.Header().Set("Content-Disposition", "attachment; filename=test.zip")
            rw.Header().Set("Content-Type", "application/zip")
            _ = writer.Close()
    
            http.ServeContent(rw, r, "test.zip", time.Now(), bytes.NewReader(buf.Bytes()))
        })))