2023-02-14 10:58:12 +00:00
|
|
|
package router
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/leafee98/paste-abroad/internel/storage"
|
|
|
|
|
|
|
|
"log"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
"strconv"
|
|
|
|
"bytes"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
var store storage.Storage
|
2023-02-15 04:09:09 +00:00
|
|
|
var defaultExpireTime int64
|
2023-02-14 10:58:12 +00:00
|
|
|
|
2023-02-15 04:09:09 +00:00
|
|
|
func Init(e *gin.Engine, s storage.Storage, expireTime int64) {
|
|
|
|
defaultExpireTime = expireTime
|
2023-02-14 10:58:12 +00:00
|
|
|
store = s
|
|
|
|
|
2023-02-15 04:09:09 +00:00
|
|
|
e.POST("/", PostPaste)
|
|
|
|
e.GET("/raw/:id", GetPasteRaw)
|
|
|
|
e.GET("/:id", GetPaste)
|
2023-02-14 10:58:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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 {
|
2023-02-15 04:09:09 +00:00
|
|
|
content_str, exists := getRequestValue(ctx, "c", false)
|
|
|
|
if !exists {
|
|
|
|
ctx.String(400, "cannot get paste content: missing parameter \"c\"")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
content = []byte(content_str)
|
2023-02-14 10:58:12 +00:00
|
|
|
}
|
|
|
|
case "application/x-www-form-urlencoded":
|
2023-02-15 04:09:09 +00:00
|
|
|
content_str, exists := getRequestValue(ctx, "c", false)
|
|
|
|
if !exists {
|
|
|
|
ctx.String(400, "cannot get paste content: missing parameter \"c\"")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
content = []byte(content_str)
|
2023-02-14 10:58:12 +00:00
|
|
|
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 {
|
2023-02-15 04:09:09 +00:00
|
|
|
life_int = defaultExpireTime
|
2023-02-14 10:58:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
paste := storage.Paste{
|
|
|
|
Content: content,
|
|
|
|
// Content: content_buffer.Bytes(),
|
2023-02-15 04:09:09 +00:00
|
|
|
Encrypt: isEncrypt(encrypt),
|
2023-02-14 10:58:12 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-02-15 04:09:09 +00:00
|
|
|
log.Printf("Saved a paste { id: %s, encrypt: %t, expire: %d}", id, paste.Encrypt, paste.Expire)
|
2023-02-14 10:58:12 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-02-15 04:09:09 +00:00
|
|
|
if content.Encrypt {
|
2023-02-14 10:58:12 +00:00
|
|
|
ctx.Data(200, "application/octet-stream", content.Content)
|
2023-02-15 04:09:09 +00:00
|
|
|
} else {
|
|
|
|
ctx.Data(200, "text/plain", content.Content)
|
2023-02-14 10:58:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-02-15 04:09:09 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-02-14 10:58:12 +00:00
|
|
|
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
|
|
|
|
}
|