I have gzipped files on disk that I wish to stream to an HTTP client uncompressed. To do this I need to send a length header, then stream the uncompressed file to the client. I know the gzip protocol stores the original length of the uncompressed data, but as far as I can tell golang's "compress/gzip" package does not appear to have a way to grab this length. I've resorted to reading the file into a variable then taking the string length from that, but this is grossly inefficient and wasteful of memory especially on larger files.
Bellow I've posted the code I've ended up using:
DownloadHandler(w http.ResponseWriter, r *http.Request) {
path := "/path/to/thefile.gz";
openfile, err := os.Open(path);
if err != nil {
w.WriteHeader(http.StatusNotFound);
fmt.Fprint(w, "404");
return;
}
defer openfile.Close();
fz, err := gzip.NewReader(openfile);
if err != nil {
w.WriteHeader(http.StatusNotFound);
fmt.Fprint(w, "404");
return;
}
defer fz.Close()
// Wastefully read data into a string so I can get the length.
s, err := ioutil.ReadAll(fz);
r := strings.NewReader(string(s));
//Send the headers
w.Header().Set("Content-Disposition", "attachment; filename=test");
w.Header().Set("Content-Length", strconv.Itoa(len(s))); // Send length to client.
w.Header().Set("Content-Type", "text/csv");
io.Copy(w, r) //'Copy' the file to the client
}
What I would expect to be able to do instead is something like this:
DownloadHandler(w http.ResponseWriter, r *http.Request) {
path := "/path/to/thefile.gz";
openfile, err := os.Open(path);
if err != nil {
w.WriteHeader(http.StatusNotFound);
fmt.Fprint(w, "404");
return;
}
defer openfile.Close();
fz, err := gzip.NewReader(openfile);
if err != nil {
w.WriteHeader(http.StatusNotFound);
fmt.Fprint(w, "404");
return;
}
defer fz.Close()
//Send the headers
w.Header().Set("Content-Disposition", "attachment; filename=test");
w.Header().Set("Content-Length", strconv.Itoa(fz.Length())); // Send length to client.
w.Header().Set("Content-Type", "text/csv");
io.Copy(w, fz) //'Copy' the file to the client
}
Does anyone know how to get the uncompressed length for a gzipped file in golang?