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.
		
		
		
		
		
			
		
			
				
					
					
						
							153 lines
						
					
					
						
							3.0 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							153 lines
						
					
					
						
							3.0 KiB
						
					
					
				| package util | |
| 
 | |
| import ( | |
| 	"bytes" | |
| 	"fmt" | |
| 	"strings" | |
| 
 | |
| 	"github.com/seaweedfs/seaweedfs/weed/glog" | |
| 	// "github.com/klauspost/compress/zstd" | |
| ) | |
| 
 | |
| var ( | |
| 	UnsupportedCompression = fmt.Errorf("unsupported compression") | |
| ) | |
| 
 | |
| func MaybeGzipData(input []byte) []byte { | |
| 	if IsGzippedContent(input) { | |
| 		return input | |
| 	} | |
| 	gzipped, err := GzipData(input) | |
| 	if err != nil { | |
| 		return input | |
| 	} | |
| 	if len(gzipped)*10 > len(input)*9 { | |
| 		return input | |
| 	} | |
| 	return gzipped | |
| } | |
| 
 | |
| func MaybeDecompressData(input []byte) []byte { | |
| 	uncompressed, err := DecompressData(input) | |
| 	if err != nil { | |
| 		if err != UnsupportedCompression { | |
| 			glog.Errorf("decompressed data: %v", err) | |
| 		} | |
| 		return input | |
| 	} | |
| 	return uncompressed | |
| } | |
| 
 | |
| func GzipData(input []byte) ([]byte, error) { | |
| 	w := new(bytes.Buffer) | |
| 	_, err := GzipStream(w, bytes.NewReader(input)) | |
| 	if err != nil { | |
| 		return nil, err | |
| 	} | |
| 	return w.Bytes(), nil | |
| } | |
| 
 | |
| func ungzipData(input []byte) ([]byte, error) { | |
| 	w := new(bytes.Buffer) | |
| 	_, err := GunzipStream(w, bytes.NewReader(input)) | |
| 	if err != nil { | |
| 		return nil, err | |
| 	} | |
| 	return w.Bytes(), nil | |
| } | |
| 
 | |
| func DecompressData(input []byte) ([]byte, error) { | |
| 	if IsGzippedContent(input) { | |
| 		return ungzipData(input) | |
| 	} | |
| 	/* | |
| 		if IsZstdContent(input) { | |
| 			return unzstdData(input) | |
| 		} | |
| 	*/ | |
| 	return input, UnsupportedCompression | |
| } | |
| 
 | |
| func IsGzippedContent(data []byte) bool { | |
| 	if len(data) < 2 { | |
| 		return false | |
| 	} | |
| 	return data[0] == 31 && data[1] == 139 | |
| } | |
| 
 | |
| /* | |
| var zstdEncoder, _ = zstd.NewWriter(nil) | |
|  | |
| func ZstdData(input []byte) ([]byte, error) { | |
| 	return zstdEncoder.EncodeAll(input, nil), nil | |
| } | |
|  | |
| var decoder, _ = zstd.NewReader(nil) | |
|  | |
| func unzstdData(input []byte) ([]byte, error) { | |
| 	return decoder.DecodeAll(input, nil) | |
| } | |
|  | |
| func IsZstdContent(data []byte) bool { | |
| 	if len(data) < 4 { | |
| 		return false | |
| 	} | |
| 	return data[3] == 0xFD && data[2] == 0x2F && data[1] == 0xB5 && data[0] == 0x28 | |
| } | |
| */ | |
| 
 | |
| /* | |
| * Default not to compressed since compression can be done on client side. | |
|  */func IsCompressableFileType(ext, mtype string) (shouldBeCompressed, iAmSure bool) { | |
| 
 | |
| 	// text | |
| 	if strings.HasPrefix(mtype, "text/") { | |
| 		return true, true | |
| 	} | |
| 
 | |
| 	// images | |
| 	switch ext { | |
| 	case ".svg", ".bmp", ".wav": | |
| 		return true, true | |
| 	} | |
| 	if strings.HasPrefix(mtype, "image/") { | |
| 		return false, true | |
| 	} | |
| 
 | |
| 	// by file name extension | |
| 	switch ext { | |
| 	case ".zip", ".rar", ".gz", ".bz2", ".xz", ".zst", ".br": | |
| 		return false, true | |
| 	case ".pdf", ".txt", ".html", ".htm", ".css", ".js", ".json": | |
| 		return true, true | |
| 	case ".php", ".java", ".go", ".rb", ".c", ".cpp", ".h", ".hpp": | |
| 		return true, true | |
| 	case ".png", ".jpg", ".jpeg": | |
| 		return false, true | |
| 	} | |
| 
 | |
| 	// by mime type | |
| 	if strings.HasPrefix(mtype, "application/") { | |
| 		if strings.HasSuffix(mtype, "zstd") { | |
| 			return false, true | |
| 		} | |
| 		if strings.HasSuffix(mtype, "xml") { | |
| 			return true, true | |
| 		} | |
| 		if strings.HasSuffix(mtype, "script") { | |
| 			return true, true | |
| 		} | |
| 		if strings.HasSuffix(mtype, "vnd.rar") { | |
| 			return false, true | |
| 		} | |
| 	} | |
| 
 | |
| 	if strings.HasPrefix(mtype, "audio/") { | |
| 		switch strings.TrimPrefix(mtype, "audio/") { | |
| 		case "wave", "wav", "x-wav", "x-pn-wav": | |
| 			return true, true | |
| 		} | |
| 	} | |
| 
 | |
| 	return false, false | |
| }
 |