diff --git a/backend/types/view_type.go b/backend/types/view_type.go index bf0180a..6ea3280 100644 --- a/backend/types/view_type.go +++ b/backend/types/view_type.go @@ -9,3 +9,6 @@ const BINARY = "Binary" const GZIP = "GZip" const GZIP_JSON = "GZip JSON" const DEFLATE = "Deflate" +const DEFLATE_JSON = "Deflate JSON" +const BROTLI = "Brotli" +const BROTLI_JSON = "Brotli JSON" diff --git a/backend/utils/string/convert.go b/backend/utils/string/convert.go index aafa176..d2a06c7 100644 --- a/backend/utils/string/convert.go +++ b/backend/utils/string/convert.go @@ -9,6 +9,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/andybalholm/brotli" "io" "strconv" "strings" @@ -72,7 +73,7 @@ func ConvertTo(str, targetType string) (value, resultType string) { case types.GZIP, types.GZIP_JSON: if gzipStr, ok := decodeGZip(str); ok { - if targetType == types.BASE64_JSON { + if targetType == types.GZIP_JSON { value, _ = decodeJson(gzipStr) } else { value = gzipStr @@ -83,8 +84,29 @@ func ConvertTo(str, targetType string) (value, resultType string) { resultType = targetType return - case types.DEFLATE: - value, _ = decodeDeflate(str) + case types.DEFLATE, types.DEFLATE_JSON: + if deflateStr, ok := decodeDeflate(str); ok { + if targetType == types.DEFLATE_JSON { + value, _ = decodeJson(deflateStr) + } else { + value = deflateStr + } + } else { + value = str + } + resultType = targetType + return + + case types.BROTLI, types.BROTLI_JSON: + if brotliStr, ok := decodeBrotli(str); ok { + if targetType == types.BROTLI_JSON { + value, _ = decodeJson(brotliStr) + } else { + value = brotliStr + } + } else { + value = str + } resultType = targetType return } @@ -122,10 +144,23 @@ func autoToType(str string) (value, resultType string) { } if value, ok = decodeDeflate(str); ok { + if value, ok = decodeJson(value); ok { + resultType = types.DEFLATE_JSON + return + } resultType = types.DEFLATE return } + if value, ok = decodeBrotli(str); ok { + if value, ok = decodeJson(value); ok { + resultType = types.BROTLI_JSON + return + } + resultType = types.BROTLI + return + } + if isBinary(str) { if value, ok = decodeHex(str); ok { resultType = types.HEX @@ -207,6 +242,14 @@ func decodeDeflate(str string) (string, bool) { return str, false } +func decodeBrotli(str string) (string, bool) { + reader := brotli.NewReader(strings.NewReader(str)) + if decompressed, err := io.ReadAll(reader); err == nil { + return string(decompressed), true + } + return str, false +} + func SaveAs(str, targetType string) (value string, err error) { switch targetType { case types.PLAIN_TEXT: @@ -224,7 +267,7 @@ func SaveAs(str, targetType string) (value string, err error) { binStr, _ := encodeBinary(str) return binStr, nil - case types.JSON, types.BASE64_JSON, types.GZIP_JSON: + case types.JSON, types.BASE64_JSON, types.GZIP_JSON, types.DEFLATE_JSON, types.BROTLI_JSON: if jsonStr, ok := encodeJson(str); ok { switch targetType { case types.BASE64_JSON: @@ -233,6 +276,12 @@ func SaveAs(str, targetType string) (value string, err error) { case types.GZIP_JSON: gzipStr, _ := encodeGZip(jsonStr) return gzipStr, nil + case types.DEFLATE_JSON: + deflateStr, _ := encodeDeflate(jsonStr) + return deflateStr, nil + case types.BROTLI_JSON: + brotliStr, _ := encodeBrotli(jsonStr) + return brotliStr, nil default: return jsonStr, nil } @@ -253,6 +302,13 @@ func SaveAs(str, targetType string) (value string, err error) { } else { return str, errors.New("fail to build deflate data") } + + case types.BROTLI: + if brotliStr, ok := encodeBrotli(str); ok { + return brotliStr, nil + } else { + return str, errors.New("fail to build brotli data") + } } return str, errors.New("fail to save with unknown error") } @@ -332,3 +388,20 @@ func encodeDeflate(str string) (string, bool) { } return str, false } + +func encodeBrotli(str string) (string, bool) { + var compress = func(b []byte) (string, error) { + var buf bytes.Buffer + writer := brotli.NewWriter(&buf) + if _, err := writer.Write([]byte(str)); err != nil { + writer.Close() + return "", err + } + writer.Close() + return string(buf.Bytes()), nil + } + if brotliStr, err := compress([]byte(str)); err == nil { + return brotliStr, true + } + return str, false +} diff --git a/frontend/src/components/content_value/ContentValueString.vue b/frontend/src/components/content_value/ContentValueString.vue index a0b7762..e55415f 100644 --- a/frontend/src/components/content_value/ContentValueString.vue +++ b/frontend/src/components/content_value/ContentValueString.vue @@ -67,6 +67,8 @@ const viewLanguage = computed(() => { case types.JSON: case types.BASE64_JSON: case types.GZIP_JSON: + case types.DEFLATE_JSON: + case types.BROTLI_JSON: return 'json' default: return 'plaintext' @@ -144,6 +146,7 @@ const onSaveValue = async () => { :value="props.viewAs" :options="viewOption" style="width: 200px" + filterable @update:value="onViewTypeUpdate" />
diff --git a/frontend/src/consts/value_view_type.js b/frontend/src/consts/value_view_type.js index d101788..ccb4677 100644 --- a/frontend/src/consts/value_view_type.js +++ b/frontend/src/consts/value_view_type.js @@ -12,4 +12,7 @@ export const types = { GZIP: 'GZip', GZIP_JSON: 'GZip JSON', DEFLATE: 'Deflate', + DEFLATE_JSON: 'Deflate JSON', + BROTLI: 'Brotli', + BROTLI_JSON: 'Brotli JSON', } diff --git a/go.mod b/go.mod index 5540745..dce3d82 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21 require ( github.com/adrg/sysfont v0.1.2 + github.com/andybalholm/brotli v1.0.5 github.com/redis/go-redis/v9 v9.2.1 github.com/vrischmann/userdir v0.0.0-20151206171402-20f291cebd68 github.com/wailsapp/wails/v2 v2.6.0 diff --git a/go.sum b/go.sum index 3fe1fe6..3e21be9 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/adrg/sysfont v0.1.2/go.mod h1:6d3l7/BSjX9VaeXWJt9fcrftFaD/t7l11xgSywC github.com/adrg/xdg v0.3.0/go.mod h1:7I2hH/IT30IsupOpKZ5ue7/qNi3CoKzD6tL3HwpaRMQ= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=