Fix 500 errors on file routes when accessing a file that doesn't exist

This commit is contained in:
Matthew Penner 2020-07-31 16:01:32 -06:00
parent 373dbd355e
commit e85b1cecb7
3 changed files with 36 additions and 6 deletions

View File

@ -3,6 +3,7 @@ package router
import ( import (
"bufio" "bufio"
"context" "context"
"errors"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/pterodactyl/wings/server" "github.com/pterodactyl/wings/server"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
@ -129,7 +130,17 @@ func putServerRenameFiles(c *gin.Context) {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
default: default:
return s.Filesystem.Rename(pf, pt) if err := s.Filesystem.Rename(pf, pt); err != nil {
// Return nil if the error is an is not exists.
// NOTE: os.IsNotExist() does not work if the error is wrapped.
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}
return nil
} }
}) })
} }
@ -155,6 +166,13 @@ func postServerCopyFile(c *gin.Context) {
} }
if err := s.Filesystem.Copy(data.Location); err != nil { if err := s.Filesystem.Copy(data.Location); err != nil {
// Check if the file does not exist.
// NOTE: os.IsNotExist() does not work if the error is wrapped.
if errors.Is(err, os.ErrNotExist) {
c.Status(http.StatusNotFound)
return
}
TrackedServerError(err, s).AbortWithServerError(c) TrackedServerError(err, s).AbortWithServerError(c)
return return
} }
@ -177,7 +195,7 @@ func postServerDeleteFiles(c *gin.Context) {
if len(data.Files) == 0 { if len(data.Files) == 0 {
c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{ c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
"error": "No files were specififed for deletion.", "error": "No files were specified for deletion.",
}) })
return return
} }
@ -311,6 +329,13 @@ func postServerDecompressFiles(c *gin.Context) {
} }
if err := s.Filesystem.DecompressFile(data.RootPath, data.File); err != nil { if err := s.Filesystem.DecompressFile(data.RootPath, data.File); err != nil {
// Check if the file does not exist.
// NOTE: os.IsNotExist() does not work if the error is wrapped.
if errors.Is(err, os.ErrNotExist) {
c.Status(http.StatusNotFound)
return
}
TrackedServerError(err, s).AbortWithServerError(c) TrackedServerError(err, s).AbortWithServerError(c)
return return
} }

View File

@ -40,8 +40,8 @@ func IsPathResolutionError(err error) bool {
} }
type Filesystem struct { type Filesystem struct {
Server *Server Server *Server
cacheDiskMu sync.Mutex cacheDiskMu sync.Mutex
} }
// Returns the root path that contains all of a server's data. // Returns the root path that contains all of a server's data.
@ -424,7 +424,7 @@ func (fs *Filesystem) unsafeStat(p string) (*Stat, error) {
return st, nil return st, nil
} }
// Creates a new directory (name) at a specificied path (p) for the server. // Creates a new directory (name) at a specified path (p) for the server.
func (fs *Filesystem) CreateDirectory(name string, p string) error { func (fs *Filesystem) CreateDirectory(name string, p string) error {
cleaned, err := fs.SafePath(path.Join(p, name)) cleaned, err := fs.SafePath(path.Join(p, name))
if err != nil { if err != nil {
@ -540,7 +540,7 @@ func (fs *Filesystem) Copy(p string) error {
} }
if s, err := os.Stat(cleaned); err != nil { if s, err := os.Stat(cleaned); err != nil {
return err return errors.WithStack(err)
} else if s.IsDir() || !s.Mode().IsRegular() { } else if s.IsDir() || !s.Mode().IsRegular() {
// If this is a directory or not a regular file, just throw a not-exist error // If this is a directory or not a regular file, just throw a not-exist error
// since anything calling this function should understand what that means. // since anything calling this function should understand what that means.

View File

@ -73,6 +73,11 @@ func (fs *Filesystem) DecompressFile(dir string, file string) error {
return errors.WithStack(err) return errors.WithStack(err)
} }
// Make sure the file exists basically.
if _, err := os.Stat(source); err != nil {
return errors.WithStack(err)
}
// Walk over all of the files spinning up an additional go-routine for each file we've encountered // Walk over all of the files spinning up an additional go-routine for each file we've encountered
// and then extract that file from the archive and write it to the disk. If any part of this process // and then extract that file from the archive and write it to the disk. If any part of this process
// encounters an error the entire process will be stopped. // encounters an error the entire process will be stopped.