| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 | package mainimport (	"encoding/json"	"errors"	"io"	"net/http"	"os"	"path"	"strings"	"github.com/labstack/echo/v4"	"github.com/nyudlts/bytemath")// GET /func MainHandle(c echo.Context) error {	m := map[string]any{		"cod":     200,		"id":      "JGoServer",		"version": "1.0-dev",	}	ents, err := os.ReadDir("storage")	if errors.Is(err, os.ErrNotExist) {		err2 := os.Mkdir("storage", 0775)		if err2 != nil {			m["cod"] = 500			m["dirs"] = nil // This is what we were trying to populate			m["err"] = err2.Error()			m["cause"] = err.Error()			return c.JSON(m["cod"].(int), m)		}	} else if err != nil {		m["cod"] = 500		m["dirs"] = nil // This is what we were trying to populate		m["err"] = err.Error()		return c.JSON(m["cod"].(int), m)	}	dirs := []string{}	for _, e := range ents {		if e.IsDir() {			dirs = append(dirs, e.Name())		}	}	m["dirs"] = dirs	return c.JSON(m["cod"].(int), m)}// Sanitizes directory name so it's a little safefunc CleanDirName(raw string) string {	return strings.ToLower(strings.Trim(raw, " .\r\n\t"))}// GET /dir?q=<dir>func GetDirHandle(c echo.Context) error {	m := map[string]any{		"cod": 200,	}	target := CleanDirName(c.QueryParam("q")) // Directory to list	if len(target) == 0 || target == "" {		// Nothing todo?		m["cod"] = http.StatusBadRequest		m["q"] = c.QueryParam("q")		return c.JSON(m["cod"].(int), m)	}	// Verify the directory at least exists	_, err := os.Stat(path.Join("storage", target))	if errors.Is(err, os.ErrNotExist) {		err2 := os.MkdirAll(path.Join("storage", target), 0775)		if err2 != nil {			m["cod"] = 500			m["files"] = nil			m["dirs"] = nil			m["err"] = err2.Error()			m["cause"] = err.Error()			return c.JSON(m["cod"].(int), m)		}	} else if err != nil {		m["cod"] = 500		m["files"] = nil		m["dirs"] = nil		m["err"] = err.Error()		return c.JSON(m["cod"].(int), m)	}	// Scan the dirs looking for files (won't include ones that start with .)	var scanDir func(string) ([]string, []string, error)	scanDir = func(dir string) ([]string, []string, error) {		ents, err := os.ReadDir(dir)		if err != nil {			return nil, nil, err		}		fs := []string{}		ds := []string{}		for _, e := range ents {			if strings.HasPrefix(e.Name(), ".") { // Keep hidden files/dirs hidden				continue			}			if e.IsDir() {				ds = append(ds, path.Join(dir, e.Name()))				f, d, err := scanDir(path.Join(dir, e.Name()))				if err != nil {					return nil, nil, err				}				fs = append(fs, f...)				ds = append(ds, d...)			} else {				fs = append(fs, path.Join(dir, e.Name()))			}		}		return fs, ds, nil	}	files, dirs, err2 := scanDir(path.Join("storage", target))	if err2 != nil {		m["cod"] = 500		m["files"] = nil		m["dirs"] = nil		m["err"] = err.Error()		return c.JSON(m["cod"].(int), m)	}	m["files"] = files	m["dirs"] = dirs	return c.JSON(m["cod"].(int), m)}// POST/PUT /up?q=<filepath>func UploadJData(c echo.Context) error {	// e.g. test/dir1/pkt001.json	targetDir := CleanDirName(path.Dir(c.QueryParam("q"))) // e.g. test/dir1	targetName := path.Base(c.QueryParam("q"))             // e.g. pkt001.json	_, err := os.Stat(path.Join("storage", targetDir))	if errors.Is(err, os.ErrNotExist) {		err2 := os.MkdirAll(path.Join("storage", targetDir), 0775)		if err2 != nil {			return c.JSON(500, map[string]any{				"cod":   500,				"err":   err2.Error(),				"cause": err.Error(),			})		}	} else if err != nil {		return c.JSON(500, map[string]any{			"cod": 500,			"err": err.Error(),		})	}	fh, err := os.Create(path.Join("storage", targetDir, targetName))	if err != nil {		return c.JSON(500, map[string]any{			"cod": 500,			"err": err.Error(),		})	}	body := c.Request().Body	defer body.Close()	written, err := io.Copy(fh, body)	fh.Close()	if err != nil {		return c.JSON(500, map[string]any{			"cod": 500,			"err": err.Error(),		})	}	// Check that it is in fact really JSON	data, err := os.ReadFile(path.Join("storage", targetDir, targetName))	if err != nil {		return c.JSON(500, map[string]any{			"cod": 500,			"err": err.Error(),		})	}	var test any	err = json.Unmarshal(data, &test)	if err != nil {		// Not json!		err2 := os.Remove(path.Join("storage", targetDir, targetName))		if err2 != nil {			return c.JSON(500, map[string]any{				"cod":   500,				"err":   err2.Error(),				"cause": err.Error(),			})		}		return c.JSON(500, map[string]any{			"cod": 500,			"err": err.Error(),		})	}	// Ok we're good	return c.JSON(200, map[string]any{		"cod":  200,		"size": bytemath.ConvertBytesToHumanReadable(written),	})}// GET /down?q=<filepath>func DownloadJData(c echo.Context) error {	// e.g. test/dir1/pkt001.json	targetDir := CleanDirName(path.Dir(c.QueryParam("q"))) // e.g. test/dir1	targetName := path.Base(c.QueryParam("q"))             // e.g. pkt001.json	_, err := os.ReadDir(path.Join("storage", targetDir))	if errors.Is(err, os.ErrNotExist) {		err2 := os.MkdirAll(path.Join("storage", targetDir), 0775)		if err2 != nil {			return c.JSON(500, map[string]any{				"cod":   500,				"err":   err2.Error(),				"cause": err.Error(),			})		}	} else if err != nil {		return c.JSON(500, map[string]any{			"cod": 500,			"err": err.Error(),		})	}	// File contents must be JSON, we live in JSON so it must be JSON data	fh, err := os.ReadFile(path.Join("storage", targetDir, targetName))	if err != nil {		return c.JSON(500, map[string]any{			"cod":  500,			"err":  "ReadFile: " + err.Error(),			"data": nil,		})	}	var data any	err = json.Unmarshal(fh, &data)	if err != nil {		return c.JSON(500, map[string]any{			"cod":  500,			"err":  "json.Unmarshal: " + err.Error(),			"data": nil,		})	}	return c.JSON(200, map[string]any{		"cod":  200,		"data": data,		"size": bytemath.ConvertBytesToHumanReadable(int64(len(fh))),	})}
 |