Merge pull request #160 from Enrico204/reply-with-insufficient-storage-on-disk-full

Reply "insufficient storage" on disk full or over-quota
This commit is contained in:
MichaelEischer 2021-09-07 21:28:07 +02:00 committed by GitHub
commit 1172d7e068
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 5 deletions

View file

@ -3,6 +3,7 @@ package repo
import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -13,6 +14,7 @@ import (
"regexp"
"runtime"
"strings"
"syscall"
"time"
"github.com/minio/sha256-simd"
@ -83,6 +85,10 @@ func httpMethodNotAllowed(w http.ResponseWriter, allowed []string) {
httpDefaultError(w, http.StatusMethodNotAllowed)
}
// errFileContentDoesntMatchHash is the error raised when the file content hash
// doesn't match the hash provided in the URL
var errFileContentDoesntMatchHash = errors.New("file content does not match hash")
// BlobPathRE matches valid blob URI paths with optional object IDs
var BlobPathRE = regexp.MustCompile(`^/(data|index|keys|locks|snapshots)/([0-9a-f]{64})?$`)
@ -592,7 +598,7 @@ func (h *Handler) saveBlob(w http.ResponseWriter, r *http.Request) {
// reject if file content doesn't match file name
if err == nil && hex.EncodeToString(hasher.Sum(nil)) != objectID {
err = fmt.Errorf("file content does not match hash")
err = errFileContentDoesntMatchHash
}
}
@ -603,7 +609,23 @@ func (h *Handler) saveBlob(w http.ResponseWriter, r *http.Request) {
if h.opt.Debug {
log.Print(err)
}
httpDefaultError(w, http.StatusBadRequest)
var pathError *os.PathError
if errors.As(err, &pathError) && (pathError.Err == syscall.ENOSPC ||
pathError.Err == syscall.EDQUOT) {
// The error is disk-related (no space left, no quota left),
// notify the client using the correct HTTP status
httpDefaultError(w, http.StatusInsufficientStorage)
} else if errors.Is(err, errFileContentDoesntMatchHash) ||
errors.Is(err, io.ErrUnexpectedEOF) ||
errors.Is(err, http.ErrMissingBoundary) ||
errors.Is(err, http.ErrNotMultipart) {
// The error is connection-related, send a client-side HTTP status
httpDefaultError(w, http.StatusBadRequest)
} else {
// Otherwise we have a different internal error, reply with
// server-side HTTP status
h.internalServerError(w, err)
}
return
}