2020-04-06 01:00:33 +00:00
|
|
|
package router
|
2020-04-06 01:56:54 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2020-09-01 03:24:07 +00:00
|
|
|
"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
|
|
|
)
|
|
|
|
|
2020-04-07 03:27:57 +00:00
|
|
|
// Handle a download request for a server backup.
|
2020-04-06 01:56:54 +00:00
|
|
|
func getDownloadBackup(c *gin.Context) {
|
2021-01-26 04:28:24 +00:00
|
|
|
manager := middleware.ExtractManager(c)
|
2021-01-08 23:14:56 +00:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-04-14 05:01:07 +00:00
|
|
|
b, st, err := backup.LocateLocal(token.BackupUuid)
|
2020-04-06 01:56:54 +00:00
|
|
|
if err != nil {
|
2020-09-01 03:24:07 +00:00
|
|
|
if errors.Is(err, os.ErrNotExist) {
|
2020-04-14 05:01:07 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-04-14 05:01:07 +00:00
|
|
|
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())))
|
2021-02-21 06:41:50 +00:00
|
|
|
c.Header("Content-Disposition", "attachment; filename="+strconv.Quote(st.Name()))
|
2020-04-06 01:56:54 +00:00
|
|
|
c.Header("Content-Type", "application/octet-stream")
|
|
|
|
|
|
|
|
bufio.NewReader(f).WriteTo(c.Writer)
|
|
|
|
}
|
2020-04-07 03:27:57 +00:00
|
|
|
|
|
|
|
// 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)
|
2020-04-07 03:27:57 +00:00
|
|
|
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)
|
2020-04-07 03:27:57 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-01-26 04:28:24 +00:00
|
|
|
s, ok := manager.Get(token.ServerUuid)
|
|
|
|
if !ok || !token.IsUniqueRequest() {
|
2020-04-07 03:27:57 +00:00
|
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
|
|
|
"error": "The requested resource was not found on this server.",
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-09-27 19:24:08 +00:00
|
|
|
p, _ := s.Filesystem().SafePath(token.FilePath)
|
2020-04-07 03:27:57 +00:00
|
|
|
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)
|
2020-04-07 03:27:57 +00:00
|
|
|
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)
|
2020-04-07 03:27:57 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Header("Content-Length", strconv.Itoa(int(st.Size())))
|
2021-02-21 06:41:50 +00:00
|
|
|
c.Header("Content-Disposition", "attachment; filename="+strconv.Quote(st.Name()))
|
2020-04-07 03:27:57 +00:00
|
|
|
c.Header("Content-Type", "application/octet-stream")
|
|
|
|
|
|
|
|
bufio.NewReader(f).WriteTo(c.Writer)
|
2020-09-05 19:08:40 +00:00
|
|
|
}
|