mirror of https://github.com/dnomd343/XProxy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.0 KiB
80 lines
2.0 KiB
package assets
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/bzip2"
|
|
"github.com/gabriel-vasile/mimetype"
|
|
"github.com/klauspost/compress/gzip"
|
|
"github.com/ulikunitz/xz"
|
|
"io"
|
|
)
|
|
|
|
const (
|
|
notArchive = iota
|
|
gzipArchive
|
|
bzip2Archive
|
|
xzArchive
|
|
)
|
|
|
|
// gzipExtract use to extract independent gzip format stream.
|
|
func gzipExtract(a *asset) error {
|
|
a.debug("Start extracting gzip archive stream")
|
|
reader, err := gzip.NewReader(a.stream)
|
|
if err != nil {
|
|
a.error("Failed to extract gzip archive -> %v", err)
|
|
return err
|
|
}
|
|
a.stream, a.archive = reader, gzipArchive
|
|
return nil
|
|
}
|
|
|
|
// bzip2Extract use to extract independent bzip2 format stream.
|
|
func bzip2Extract(a *asset) error {
|
|
a.debug("Start extracting bzip2 archive stream")
|
|
a.stream = bzip2.NewReader(a.stream)
|
|
a.archive = bzip2Archive
|
|
return nil
|
|
}
|
|
|
|
// xzExtract use to extract independent xz format stream.
|
|
func xzExtract(a *asset) error {
|
|
a.debug("Start extracting xz archive stream")
|
|
reader, err := xz.NewReader(a.stream)
|
|
if err != nil {
|
|
a.error("Failed to extract xz archive -> %v", err)
|
|
return err
|
|
}
|
|
a.stream, a.archive = reader, xzArchive
|
|
return nil
|
|
}
|
|
|
|
// tryExtract try to extract the data stream as a compressed format, and will
|
|
// return the original data if it cannot be determined.
|
|
func (a *asset) tryExtract() error {
|
|
if a.archive != notArchive {
|
|
return nil // already extracted
|
|
}
|
|
|
|
header := bytes.NewBuffer(nil)
|
|
mime, err := mimetype.DetectReader(io.TeeReader(a.stream, header))
|
|
if err != nil {
|
|
a.error("Failed to detect data stream -> %v", err)
|
|
return err
|
|
}
|
|
a.stream = io.MultiReader(header, a.stream) // recycle reader
|
|
|
|
switch mime.String() { // extract with detected mime type
|
|
case "application/gzip":
|
|
a.debug("Data detected as gzip format")
|
|
return gzipExtract(a)
|
|
case "application/x-bzip2":
|
|
a.debug("Data detected as bzip2 format")
|
|
return bzip2Extract(a)
|
|
case "application/x-xz":
|
|
a.debug("Data detected as xz format")
|
|
return xzExtract(a)
|
|
default:
|
|
a.debug("Data detected as non-archive format -> `%s`", mime)
|
|
return nil
|
|
}
|
|
}
|
|
|