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 defaultExpireTime int64 func Init(e *gin.Engine, s storage.Storage, expireTime int64) { defaultExpireTime = expireTime store = s e.POST("/", PostPaste) e.GET("/raw/:id", GetPasteRaw) e.GET("/:id", GetPaste) } // 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_str, exists := getRequestValue(ctx, "c", false) if !exists { ctx.String(400, "cannot get paste content: missing parameter \"c\"") return } content = []byte(content_str) } case "application/x-www-form-urlencoded": content_str, exists := getRequestValue(ctx, "c", false) if !exists { ctx.String(400, "cannot get paste content: missing parameter \"c\"") return } content = []byte(content_str) 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 = defaultExpireTime } paste := storage.Paste{ Content: content, // Content: content_buffer.Bytes(), Encrypt: 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, encrypt: %t, expire: %d}", id, paste.Encrypt, 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.Encrypt { ctx.Data(200, "application/octet-stream", content.Content) } else { ctx.Data(200, "text/plain", 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 getRequestValue(ctx *gin.Context, key string, urlPrefer bool) (string, bool) { var value string var exists bool if urlPrefer { value, exists = ctx.GetQuery(key) if !exists { value, exists = ctx.GetPostForm(key) } } else { value, exists = ctx.GetPostForm(key) if !exists { value, exists = ctx.GetQuery(key) } } return value, exists } 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 }