Better error handling; skip file when unarchiving
This commit is contained in:
parent
b10e4dd437
commit
e9e70b6081
|
@ -77,7 +77,6 @@ func (e *RequestError) AbortWithStatus(status int, c *gin.Context) {
|
||||||
// If this error is because the resource does not exist, we likely do not need to log
|
// If this error is because the resource does not exist, we likely do not need to log
|
||||||
// the error anywhere, just return a 404 and move on with our lives.
|
// the error anywhere, just return a 404 and move on with our lives.
|
||||||
if errors.Is(e.err, os.ErrNotExist) {
|
if errors.Is(e.err, os.ErrNotExist) {
|
||||||
e.logger().Debug("encountered os.IsNotExist error while handling request")
|
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
||||||
"error": "The requested resource was not found on the system.",
|
"error": "The requested resource was not found on the system.",
|
||||||
})
|
})
|
||||||
|
@ -122,16 +121,19 @@ func (e *RequestError) Abort(c *gin.Context) {
|
||||||
// Looks at the given RequestError and determines if it is a specific filesystem error that
|
// Looks at the given RequestError and determines if it is a specific filesystem error that
|
||||||
// we can process and return differently for the user.
|
// we can process and return differently for the user.
|
||||||
func (e *RequestError) getAsFilesystemError() (int, string) {
|
func (e *RequestError) getAsFilesystemError() (int, string) {
|
||||||
if filesystem.IsErrorCode(e.err, filesystem.ErrCodePathResolution) || errors.Is(e.err, os.ErrNotExist) {
|
// Some external things end up calling fmt.Errorf() on our filesystem errors
|
||||||
return http.StatusNotFound, "The requested resource was not found on the system."
|
// which ends up just unleashing chaos on the system. For the sake of this
|
||||||
}
|
// fallback to using text checks...
|
||||||
if filesystem.IsErrorCode(e.err, filesystem.ErrCodeDiskSpace) {
|
if filesystem.IsErrorCode(e.err, filesystem.ErrCodeDenylistFile) || strings.Contains(e.err.Error(), "filesystem: file access prohibited") {
|
||||||
return http.StatusConflict, "There is not enough disk space available to perform that action."
|
|
||||||
}
|
|
||||||
if filesystem.IsErrorCode(e.err, filesystem.ErrCodeDenylistFile) {
|
|
||||||
return http.StatusForbidden, "This file cannot be modified: present in egg denylist."
|
return http.StatusForbidden, "This file cannot be modified: present in egg denylist."
|
||||||
}
|
}
|
||||||
if filesystem.IsErrorCode(e.err, filesystem.ErrCodeIsDirectory) {
|
if filesystem.IsErrorCode(e.err, filesystem.ErrCodePathResolution) || strings.Contains(e.err.Error(), "resolves to a location outside the server root") {
|
||||||
|
return http.StatusNotFound, "The requested resource was not found on the system."
|
||||||
|
}
|
||||||
|
if filesystem.IsErrorCode(e.err, filesystem.ErrCodeIsDirectory) || strings.Contains(e.err.Error(), "filesystem: is a directory") {
|
||||||
|
return http.StatusBadRequest, "Cannot perform that action: file is a directory."
|
||||||
|
}
|
||||||
|
if filesystem.IsErrorCode(e.err, filesystem.ErrCodeDiskSpace) || strings.Contains(e.err.Error(), "filesystem: not enough disk space") {
|
||||||
return http.StatusBadRequest, "Cannot perform that action: file is a directory."
|
return http.StatusBadRequest, "Cannot perform that action: file is a directory."
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(e.err.Error(), "file name too long") {
|
if strings.HasSuffix(e.err.Error(), "file name too long") {
|
||||||
|
|
|
@ -410,13 +410,6 @@ 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 {
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
|
||||||
"error": "The requested archive was not found.",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the file is busy for some reason just return a nicer error to the user since there is not
|
// If the file is busy for some reason just return a nicer error to the user since there is not
|
||||||
// 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.
|
||||||
|
@ -429,7 +422,7 @@ func postServerDecompressFiles(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
NewServerError(err, s).AbortFilesystemError(c)
|
NewServerError(err, s).Abort(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,14 +541,14 @@ func postServerUploadFiles(c *gin.Context) {
|
||||||
for _, header := range headers {
|
for _, header := range headers {
|
||||||
p, err := s.Filesystem().SafePath(filepath.Join(directory, header.Filename))
|
p, err := s.Filesystem().SafePath(filepath.Join(directory, header.Filename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
NewServerError(err, s).AbortFilesystemError(c)
|
NewServerError(err, s).Abort(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// We run this in a different method so I can use defer without any of
|
// We run this in a different method so I can use defer without any of
|
||||||
// the consequences caused by calling it in a loop.
|
// the consequences caused by calling it in a loop.
|
||||||
if err := handleFileUpload(p, s, header); err != nil {
|
if err := handleFileUpload(p, s, header); err != nil {
|
||||||
NewServerError(err, s).AbortFilesystemError(c)
|
NewServerError(err, s).Abort(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,8 +92,9 @@ func (fs *Filesystem) DecompressFile(dir string, file string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
p := filepath.Join(dir, name)
|
p := filepath.Join(dir, name)
|
||||||
|
// 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 err
|
return nil
|
||||||
}
|
}
|
||||||
return errors.WithMessage(fs.Writefile(p, f), "could not extract file from archive")
|
return errors.WithMessage(fs.Writefile(p, f), "could not extract file from archive")
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user