aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorᴜɴᴋɴᴡᴏɴ <u@gogs.io>2020-04-05 00:45:08 +0800
committerGitHub <noreply@github.com>2020-04-05 00:45:08 +0800
commit4aff4d66ec3e118248129505bc1d70395f47dfbb (patch)
tree596e3d98ecba86b4a5fdc31fd3c407dabf19cd13 /internal
parent53b91ef306166d39dea3c70fb8ce14973c7ae111 (diff)
lfs: support upload retry (#6061)
Diffstat (limited to 'internal')
1 files changed, 17 insertions, 1 deletions
diff --git a/internal/route/lfs/basic.go b/internal/route/lfs/basic.go
index f15873ad..e266c541 100644
--- a/internal/route/lfs/basic.go
+++ b/internal/route/lfs/basic.go
@@ -7,6 +7,7 @@ package lfs
import (
"encoding/json"
"io"
+ "io/ioutil"
"net/http"
"os"
"strconv"
@@ -63,7 +64,22 @@ func serveBasicDownload(c *context.Context, repo *db.Repository, oid lfsutil.OID
// PUT /{owner}/{repo}.git/info/lfs/object/basic/{oid}
func serveBasicUpload(c *context.Context, repo *db.Repository, oid lfsutil.OID) {
- err := db.LFS.CreateObject(repo.ID, oid, c.Req.Request.Body, lfsutil.StorageLocal)
+ // NOTE: LFS client will retry upload the same object if there was a partial failure,
+ // therefore we would like to skip ones that already exist.
+ _, err := db.LFS.GetObjectByOID(repo.ID, oid)
+ if err == nil {
+ // Object exists, drain the request body and we're good.
+ _, _ = io.Copy(ioutil.Discard, c.Req.Request.Body)
+ c.Req.Request.Body.Close()
+ c.Status(http.StatusOK)
+ return
+ } else if !db.IsErrLFSObjectNotExist(err) {
+ internalServerError(c.Resp)
+ log.Error("Failed to get object [repo_id: %d, oid: %s]: %v", repo.ID, oid, err)
+ return
+ }
+
+ err = db.LFS.CreateObject(repo.ID, oid, c.Req.Request.Body, lfsutil.StorageLocal)
if err != nil {
internalServerError(c.Resp)
log.Error("Failed to create object [repo_id: %d, oid: %s]: %v", repo.ID, oid, err)