Fix .rar file decompression; closes pterodactyl/panel#3267
This commit is contained in:
parent
16b0ca3a8e
commit
4b244e96fb
|
@ -383,8 +383,6 @@ func postServerCompressFiles(c *gin.Context) {
|
||||||
// of unpacking an archive that exists on the server into the provided RootPath
|
// of unpacking an archive that exists on the server into the provided RootPath
|
||||||
// for the server.
|
// for the server.
|
||||||
func postServerDecompressFiles(c *gin.Context) {
|
func postServerDecompressFiles(c *gin.Context) {
|
||||||
s := middleware.ExtractServer(c)
|
|
||||||
lg := middleware.ExtractLogger(c)
|
|
||||||
var data struct {
|
var data struct {
|
||||||
RootPath string `json:"root"`
|
RootPath string `json:"root"`
|
||||||
File string `json:"file"`
|
File string `json:"file"`
|
||||||
|
@ -393,7 +391,8 @@ func postServerDecompressFiles(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lg = lg.WithFields(log.Fields{"root_path": data.RootPath, "file": data.File})
|
s := middleware.ExtractServer(c)
|
||||||
|
lg := middleware.ExtractLogger(c).WithFields(log.Fields{"root_path": data.RootPath, "file": data.File})
|
||||||
lg.Debug("checking if space is available for file decompression")
|
lg.Debug("checking if space is available for file decompression")
|
||||||
err := s.Filesystem().SpaceAvailableForDecompression(data.RootPath, data.File)
|
err := s.Filesystem().SpaceAvailableForDecompression(data.RootPath, data.File)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -412,7 +411,7 @@ func postServerDecompressFiles(c *gin.Context) {
|
||||||
// much we specifically can do. They'll need to stop the running server process in order to overwrite
|
// much we specifically can do. They'll need to stop the running server process in order to overwrite
|
||||||
// a file like this.
|
// a file like this.
|
||||||
if strings.Contains(err.Error(), "text file busy") {
|
if strings.Contains(err.Error(), "text file busy") {
|
||||||
lg.WithField("error", err).Warn("failed to decompress file: text file busy")
|
lg.WithField("error", errors.WithStackIf(err)).Warn("failed to decompress file: text file busy")
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "One or more files this archive is attempting to overwrite are currently in use by another process. Please try again.",
|
"error": "One or more files this archive is attempting to overwrite are currently in use by another process. Please try again.",
|
||||||
})
|
})
|
||||||
|
|
|
@ -121,11 +121,7 @@ func (fs *Filesystem) DecompressFile(dir string, file string) error {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
name, err := system.ExtractArchiveSourceName(f, dir)
|
p := filepath.Join(dir, f.Name())
|
||||||
if err != nil {
|
|
||||||
return WrapError(err, filepath.Join(dir, f.Name()))
|
|
||||||
}
|
|
||||||
p := filepath.Join(dir, name)
|
|
||||||
// If it is ignored, just don't do anything with the file and skip over it.
|
// If it is ignored, just don't do anything with the file and skip over it.
|
||||||
if err := fs.IsIgnored(p); err != nil {
|
if err := fs.IsIgnored(p); err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,23 +1,18 @@
|
||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
|
||||||
"archive/zip"
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"emperror.dev/errors"
|
"emperror.dev/errors"
|
||||||
"github.com/mholt/archiver/v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var cr = []byte(" \r")
|
var cr = []byte(" \r")
|
||||||
|
@ -41,22 +36,6 @@ func MustInt(v string) int {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractArchiveSourceName looks for the provided archiver.File's name if it is
|
|
||||||
// a type that is supported, otherwise it returns an error to the caller.
|
|
||||||
func ExtractArchiveSourceName(f archiver.File, dir string) (name string, err error) {
|
|
||||||
switch s := f.Sys().(type) {
|
|
||||||
case *tar.Header:
|
|
||||||
name = s.Name
|
|
||||||
case *gzip.Header:
|
|
||||||
name = s.Name
|
|
||||||
case *zip.FileHeader:
|
|
||||||
name = s.Name
|
|
||||||
default:
|
|
||||||
err = errors.New(fmt.Sprintf("could not parse underlying data source with type: %s", reflect.TypeOf(s).String()))
|
|
||||||
}
|
|
||||||
return name, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func ScanReader(r io.Reader, callback func(line string)) error {
|
func ScanReader(r io.Reader, callback func(line string)) error {
|
||||||
br := bufio.NewReader(r)
|
br := bufio.NewReader(r)
|
||||||
// Avoid constantly re-allocating memory when we're flooding lines through this
|
// Avoid constantly re-allocating memory when we're flooding lines through this
|
||||||
|
|
Loading…
Reference in New Issue
Block a user