136 lines
3.1 KiB
Go
136 lines
3.1 KiB
Go
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
|
|
}
|