wings/router/router_download.go

105 lines
2.6 KiB
Go
Raw Normal View History

2020-04-06 01:00:33 +00:00
package router
2020-04-06 01:56:54 +00:00
import (
"bufio"
"errors"
2020-04-06 01:56:54 +00:00
"net/http"
"os"
"strconv"
2021-01-10 01:22:39 +00:00
"github.com/gin-gonic/gin"
2021-01-26 04:28:24 +00:00
"github.com/pterodactyl/wings/router/middleware"
2021-01-10 01:22:39 +00:00
"github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server/backup"
2020-04-06 01:56:54 +00:00
)
// Handle a download request for a server backup.
2020-04-06 01:56:54 +00:00
func getDownloadBackup(c *gin.Context) {
2021-02-02 05:32:34 +00:00
client := middleware.ExtractApiClient(c)
2021-01-26 04:28:24 +00:00
manager := middleware.ExtractManager(c)
2020-04-06 01:56:54 +00:00
token := tokens.BackupPayload{}
if err := tokens.ParseToken([]byte(c.Query("token")), &token); err != nil {
2020-12-16 05:08:00 +00:00
NewTrackedError(err).Abort(c)
2020-04-06 01:56:54 +00:00
return
}
2021-01-26 04:28:24 +00:00
s, ok := manager.Get(token.ServerUuid)
if !ok || !token.IsUniqueRequest() {
2020-04-06 01:56:54 +00:00
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
"error": "The requested resource was not found on this server.",
})
return
}
2021-02-02 05:32:34 +00:00
b, st, err := backup.LocateLocal(client, token.BackupUuid)
2020-04-06 01:56:54 +00:00
if err != nil {
if errors.Is(err, os.ErrNotExist) {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
"error": "The requested backup was not found on this server.",
})
return
}
2020-12-16 05:08:00 +00:00
NewServerError(err, s).Abort(c)
2020-04-06 01:56:54 +00:00
return
}
f, err := os.Open(b.Path())
2020-04-06 01:56:54 +00:00
if err != nil {
2020-12-16 05:08:00 +00:00
NewServerError(err, s).Abort(c)
2020-04-06 01:56:54 +00:00
return
}
defer f.Close()
c.Header("Content-Length", strconv.Itoa(int(st.Size())))
c.Header("Content-Disposition", "attachment; filename="+st.Name())
c.Header("Content-Type", "application/octet-stream")
bufio.NewReader(f).WriteTo(c.Writer)
}
// Handles downloading a specific file for a server.
func getDownloadFile(c *gin.Context) {
2021-01-26 04:28:24 +00:00
manager := middleware.ExtractManager(c)
token := tokens.FilePayload{}
if err := tokens.ParseToken([]byte(c.Query("token")), &token); err != nil {
2020-12-16 05:08:00 +00:00
NewTrackedError(err).Abort(c)
return
}
2021-01-26 04:28:24 +00:00
s, ok := manager.Get(token.ServerUuid)
if !ok || !token.IsUniqueRequest() {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
"error": "The requested resource was not found on this server.",
})
return
}
p, _ := s.Filesystem().SafePath(token.FilePath)
st, err := os.Stat(p)
// If there is an error or we're somehow trying to download a directory, just
// respond with the appropriate error.
if err != nil {
2020-12-16 05:08:00 +00:00
NewServerError(err, s).Abort(c)
return
} else if st.IsDir() {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
"error": "The requested resource was not found on this server.",
})
return
}
f, err := os.Open(p)
if err != nil {
2020-12-16 05:08:00 +00:00
NewServerError(err, s).Abort(c)
return
}
c.Header("Content-Length", strconv.Itoa(int(st.Size())))
c.Header("Content-Disposition", "attachment; filename="+st.Name())
c.Header("Content-Type", "application/octet-stream")
bufio.NewReader(f).WriteTo(c.Writer)
}