0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-16 21:56:37 -05:00

routes: improve error handling when returning blob data

We have noticed that very intermittently zot returns a 500 when copying
blob data. This is likely happening due to a io.ErrShortWrite
This commit is contained in:
Ramkumar Chinchani 2020-01-04 18:20:06 -08:00
parent 915c994c6c
commit 2eb4455df7

View file

@ -22,6 +22,7 @@ import (
_ "github.com/anuvu/zot/docs" // nolint (golint) - as required by swaggo
"github.com/anuvu/zot/errors"
"github.com/anuvu/zot/pkg/log"
"github.com/gorilla/mux"
jsoniter "github.com/json-iterator/go"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -437,7 +438,7 @@ func (rh *RouteHandler) GetBlob(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Length", fmt.Sprintf("%d", blen))
w.Header().Set(DistContentDigestKey, digest)
// return the blob data
WriteDataFromReader(w, http.StatusOK, blen, mediaType, br)
WriteDataFromReader(w, http.StatusOK, blen, mediaType, br, rh.c.Log)
}
// DeleteBlob godoc
@ -905,22 +906,21 @@ func WriteData(w http.ResponseWriter, status int, mediaType string, data []byte)
_, _ = w.Write(data)
}
func WriteDataFromReader(w http.ResponseWriter, status int, length int64, mediaType string, reader io.Reader) {
func WriteDataFromReader(w http.ResponseWriter, status int, length int64, mediaType string,
reader io.Reader, logger log.Logger) {
w.Header().Set("Content-Type", mediaType)
w.Header().Set("Content-Length", strconv.FormatInt(length, 10))
w.WriteHeader(status)
const maxSize = 10 * 1024 * 1024
for {
size, err := io.CopyN(w, reader, maxSize)
if size == 0 {
if err != io.EOF {
w.WriteHeader(http.StatusInternalServerError)
return
}
_, err := io.CopyN(w, reader, maxSize)
if err == io.EOF {
break
} else if err != nil {
// other kinds of intermittent errors can occur, e.g, io.ErrShortWrite
logger.Error().Err(err).Msg("copying data into http response")
}
}
w.WriteHeader(status)
}