]> source.dussan.org Git - gitea.git/commitdiff
repo: Download: restore some semblance of previous behavior
authorKyle Evans <kevans@FreeBSD.org>
Tue, 5 May 2020 23:56:13 +0000 (18:56 -0500)
committerKyle Evans <kevans@FreeBSD.org>
Wed, 6 May 2020 00:13:23 +0000 (19:13 -0500)
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.

routers/repo/repo.go

index 78ea55ad35fd6f10a41a598f33e37ddf6f2dc1ed..95d4701be9958cbdca03af080748258d5dcad4f6 100644 (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{}{