I made it work using golang io.Pipe().The Pipewriter writes byte to the pipe in chunks and the pipeReader reader from the other end. The reason for using a go-routine is to have a non-blocking write operation while simultaneous reads happen form the pipe.

Note: It's important to close the pipe writer (w.Close()) to send EOF on the stream otherwise it will not close the stream.

func DownloadZip() ([]byte, error) {
    r, w := io.Pipe()

    defer r.Close()
    defer w.Close()

    zip, err := os.Stat("temp.zip")
    if err != nil{
        return nil, err
    }

    go func(){

        f, err := os.Open(zip.Name())
        if err != nil {
            return

        }

        buf := make([]byte, 1024)
        for {
            chunk, err := f.Read(buf)
            if err != nil && err != io.EOF {
                panic(err)
            }
            if chunk == 0 {
                break
            }

            if _, err := w.Write(buf[:chunk]); err != nil{
                return
            }

        }

        w.Close()
    }()

    body, err := ioutil.ReadAll(r)
    if err != nil {
        return nil, err
    }
    return body, nil

}

Please let me know if someone has another way of doing it.