mirror of
https://github.com/Li4n0/revsuit.git
synced 2026-09-26 00:21:54 +08:00
feat(ftp): support upload, download and PASV rebind (#13)
Co-authored-by: E99p1ant <[email protected]>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package file
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/li4n0/revsuit/internal/database"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
ID uint `gorm:"primarykey" form:"id" json:"id"`
|
||||
RecordID uint `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
|
||||
Name string `json:"name"`
|
||||
Content []byte `json:"-"`
|
||||
}
|
||||
|
||||
type MySQLFile File
|
||||
|
||||
func (MySQLFile) TableName() string {
|
||||
return "mysql_files"
|
||||
}
|
||||
|
||||
type FTPFile File
|
||||
|
||||
func (FTPFile) TableName() string {
|
||||
return "ftp_files"
|
||||
}
|
||||
|
||||
func GetFile(c *gin.Context) {
|
||||
var file File
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": fmt.Errorf("param id missed").Error(),
|
||||
"result": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
recordType := c.Param("record_type")
|
||||
if id == "" {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": fmt.Errorf("param record_type missed"),
|
||||
"result": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
if recordType == "mysql" {
|
||||
database.DB.Table("mysql_files").Where("id = ?", id).Find(&file)
|
||||
} else if recordType == "ftp" {
|
||||
database.DB.Table("ftp_files").Where("id = ?", id).Find(&file)
|
||||
}
|
||||
|
||||
if file.Content == nil || len(file.Content) == 0 {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": fmt.Errorf("file not found").Error(),
|
||||
"result": nil,
|
||||
})
|
||||
return
|
||||
} else {
|
||||
mime := mimetype.Detect(file.Content)
|
||||
c.Header("Content-Type", mime.String())
|
||||
c.Header("Content-Disposition",
|
||||
fmt.Sprintf(
|
||||
"filename=%s_%d",
|
||||
file.Name,
|
||||
file.ID,
|
||||
),
|
||||
)
|
||||
c.String(200, string(file.Content))
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,20 @@
|
||||
package rule
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CompileTpl(tpl string, vars map[string]string) (compiled string) {
|
||||
compiled = tpl
|
||||
// CompileTpl receive []byte or string type tpl and variables map.
|
||||
// Return the template after variable substitution
|
||||
func CompileTpl(tpl interface{}, vars map[string]string) (compiled string) {
|
||||
switch v := tpl.(type) {
|
||||
case string:
|
||||
compiled = v
|
||||
case []byte:
|
||||
compiled = string(v)
|
||||
}
|
||||
for n, v := range vars {
|
||||
compiled = strings.ReplaceAll(compiled, "${"+n+"}", v)
|
||||
}
|
||||
|
||||
return compiled
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user