repo: Download: restore some semblance of previous behavior

When archival was made async, the GET endpoint was only useful if a previous
POST had initiated the download. This commit restores the previous behavior,
to an extent; we'll now submit the archive request there and return a
"202 Accepted" to indicate that it's processing if we didn't manage to
complete the request within ~2 seconds of submission.

This lets a client directly GET the archive, and gives them some indication
that they may attempt to GET it again at a later time.
This commit is contained in:
Kyle Evans 2020-05-05 18:56:13 -05:00
parent 67d491ba7c
commit c134aef340

View file

@ -9,6 +9,7 @@ import (
"fmt"
"net/url"
"strings"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
@ -478,10 +479,24 @@ func Download(ctx *context.Context) {
uri := ctx.Params("*")
aReq := archiver_service.DeriveRequestFrom(ctx, uri)
downloadName := ctx.Repo.Repository.Name + "-" + aReq.GetArchiveName()
if aReq.IsComplete() {
ctx.ServeFile(aReq.GetArchivePath(), ctx.Repo.Repository.Name+"-"+aReq.GetArchiveName())
ctx.ServeFile(aReq.GetArchivePath(), downloadName)
} else {
ctx.Error(404)
// We'll wait up to two seconds for the request to be satisfied, before we just return
// a 200 Accepted to indicate that we're processing.
archiver_service.ArchiveRepository(aReq)
timeout := time.Now().Add(2 * time.Second)
for {
if aReq.IsComplete() || time.Now().After(timeout) {
break
}
}
if aReq.IsComplete() {
ctx.ServeFile(aReq.GetArchivePath(), downloadName)
} else {
ctx.Error(202, "Request accepted, processing archive.")
}
}
}
@ -499,6 +514,18 @@ func InitiateDownload(ctx *context.Context) {
complete := aReq.IsComplete()
if !complete {
archiver_service.ArchiveRepository(aReq)
// As with the standard Download, we'll wait up to two seconds for the request
// to be completed. The difference is that we'll never download the file from a POST
// request, only indicate the current status. If we did manage to complete the request
// in this timeframe, the download will proceed with no further overhead.
timeout := time.Now().Add(2 * time.Second)
for {
if aReq.IsComplete() || time.Now().After(timeout) {
break
}
}
complete = aReq.IsComplete()
}
ctx.JSON(200, map[string]interface{}{