package selfupdate import ( "archive/tar" "archive/zip" "bytes" "compress/gzip" "fmt" "io" "io/ioutil" "strings" ) func uncompress(src io.Reader, url, cmd string) (io.Reader, error) { if strings.HasSuffix(url, ".zip") { // Zip format requires its file size for uncompressing. // So we need to read the HTTP response into a buffer at first. buf, err := ioutil.ReadAll(src) if err != nil { return nil, err } r := bytes.NewReader(buf) z, err := zip.NewReader(r, r.Size()) if err != nil { return nil, err } for _, file := range z.File { if file.Name == cmd { return file.Open() } } return nil, fmt.Errorf("File '%s' for the command is not found in %s", cmd, url) } else if strings.HasSuffix(url, ".gzip") { return gzip.NewReader(src) } else if strings.HasSuffix(url, ".tar.gz") { gz, err := gzip.NewReader(src) if err != nil { return nil, err } t := tar.NewReader(gz) for { h, err := t.Next() if err == io.EOF { break } if err != nil { return nil, err } if h.Name == cmd { return t, nil } } return nil, fmt.Errorf("File '%s' for the command is not found in %s", cmd, url) } return src, nil }