diff --git a/store/store.go b/store/store.go
index ecccf8f26..6df4c3a48 100644
--- a/store/store.go
+++ b/store/store.go
@@ -1390,12 +1390,20 @@ var download = func(ctx context.Context, name, sha3_384, downloadURL string, use
}
if finalErr != nil {
if shouldRetryError(attempt, finalErr) {
+ pos, err := w.Seek(0, os.SEEK_END)
+ if err != nil {
+ return fmt.Errorf("cannot find current position inside downloaded file: %s", err)
+ }
+ fmt.Println("***************** ", pos)
+ resume = pos
+ logger.Debugf("Retrying because of: %s", finalErr)
continue
}
break
}
if shouldRetryHttpResponse(attempt, resp) {
+ logger.Debugf("Retrying because of: %s", resp)
resp.Body.Close()
continue
}
diff --git a/store/store_test.go b/store/store_test.go
index aff445f88..25a9c2a50 100644
--- a/store/store_test.go
+++ b/store/store_test.go
@@ -326,6 +326,38 @@ func (t *remoteRepoTestSuite) TestDownloadRangeRequest(c *C) {
c.Assert(string(content), Equals, partialContentStr+"was downloaded")
}
+func (t *remoteRepoTestSuite) TestDownloadEOFretriesCorrectly(c *C) {
+ n := 0
+ var mockServer *httptest.Server
+ mockServer = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ n++
+ if n < 2 {
+ io.WriteString(w, "some ")
+ mockServer.CloseClientConnections()
+ return
+ }
+ io.WriteString(w, "data!")
+ }))
+
+ c.Assert(mockServer, NotNil)
+ defer mockServer.Close()
+
+ snap := &snap.Info{}
+ snap.RealName = "foo"
+ snap.AnonDownloadURL = mockServer.URL
+ snap.DownloadURL = "AUTH-URL"
+ // printf "some data!" | sha512sum
+ snap.Sha3_384 = "77ad0ba7f4a4ee49145630de6e38cbeefa3ac3b332f4e2a35dab8cd0937013624374777f957dd79b6ef0e83af4ad41fc5d923a463f78d060e4525c7fe3eb0eec"
+
+ targetFn := filepath.Join(c.MkDir(), "foo_1.0_all.snap")
+ err := t.store.Download(context.TODO(), "foo", targetFn, &snap.DownloadInfo, nil, nil)
+ c.Assert(err, IsNil)
+
+ content, err := ioutil.ReadFile(targetFn)
+ c.Assert(err, IsNil)
+ c.Assert(string(content), Equals, "some data!")
+}
+
func (t *remoteRepoTestSuite) TestDownloadRangeRequestRetryOnHashError(c *C) {
partialContentStr := "partial content "