From c98e061d2e5b92f06a608b2b68c6dbc40d60a034 Mon Sep 17 00:00:00 2001 From: leafee98 Date: Tue, 14 Feb 2023 18:58:12 +0800 Subject: [PATCH] finish create and get paste api --- internel/router/router.go | 135 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 internel/router/router.go diff --git a/internel/router/router.go b/internel/router/router.go new file mode 100644 index 0000000..5dfc895 --- /dev/null +++ b/internel/router/router.go @@ -0,0 +1,135 @@ +package router + +import ( + "github.com/gin-gonic/gin" + "github.com/leafee98/paste-abroad/internel/storage" + + "log" + "strings" + "time" + "strconv" + "bytes" +) + + +var store storage.Storage +var expireTime int64 + +func New(s storage.Storage, expireTime int) *gin.Engine { + store = s + + var r = gin.Default() + r.POST("/", PostPaste) + r.GET("/raw/:id", GetPasteRaw) + r.GET("/:id", GetPaste) + return r +} + +// PostPaste require two parameters from either URL or form-data +// URL parameters are preferred. +// c is paste content in bytes +// life is expire time in days +// encrypt default false, means this paste is in plain +func PostPaste(ctx *gin.Context) { + var content []byte + + switch strings.ToLower(ctx.ContentType()) { + case "multipart/form-data": + content_file, err := ctx.FormFile("c") + if err == nil { + c_reader, _ := content_file.Open() + content_buffer := new(bytes.Buffer) + content_buffer.ReadFrom(c_reader) + content = content_buffer.Bytes() + } else { + content = []byte(requestValue(ctx, "c", false)) + } + case "application/x-www-form-urlencoded": + content = []byte(requestValue(ctx, "c", false)) + default: + ctx.String(400, "unrecognized content type: %s", ctx.ContentType()) + return + } + + life := requestValue(ctx, "life", true) + encrypt := requestValue(ctx, "encrypt", true) + + life_int, err := strconv.ParseInt(life, 10, 64) + if err != nil { + life_int = expireTime + } + + paste := storage.Paste{ + Content: content, + // Content: content_buffer.Bytes(), + Plain: !isEncrypt(encrypt), + Expire: life_int * 1000 * 3600 * 24 + time.Now().UnixMilli(), + } + + id, err := store.Save(&paste) + if err != nil { + ctx.String(500, "Internel error") + log.Printf("Failed to save paste: %v", err) + return + } + + log.Printf("Saved a paste { id: %s, plain: %t, expire: %d}", id, paste.Plain, paste.Expire) + + ctx.String(200, id) +} + +func GetPasteRaw(ctx * gin.Context) { + id := ctx.Param("id") + + content, err := store.Get(id) + if err != nil { + ctx.String(500, "Internel error") + log.Printf("Failed to get paste: %v", err) + return + } + + if content == nil { + ctx.String(404, "Paste not found") + return + } + + if content.Plain { + ctx.Data(200, "text/plain", content.Content) + } else { + ctx.Data(200, "application/octet-stream", content.Content) + } +} + +func GetPaste(ctx * gin.Context) { +} + +func requestValue(ctx *gin.Context, key string, urlPrefer bool) string { + var value string + + if urlPrefer { + value = ctx.Query(key) + if value == "" { + value = ctx.PostForm(key) + } + } else { + value = ctx.PostForm(key) + if value == "" { + value = ctx.Query(key) + } + } + + return value +} + +func isEncrypt(s string) bool { + ture_values := []string{ "t", "true", "y", "yes", "1" } + + s = strings.ToLower(s) + for i := range ture_values { + if s == ture_values[i] { + return true + } + } + + return false +}