feat(one-time-downloads): add expiry and retry configuration
Introduce new environment variables to control the behavior of one-time download boxes: - `WARPBOX_ONE_TIME_DOWNLOAD_EXPIRY_SECONDS`: Sets the lifetime of a one-time box after uploads are complete. - `WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE`: Determines whether a box remains available if the ZIP creation or transfer fails. To support these settings, the ZIP delivery process was refactored to use a temporary file. This ensures that a one-time box is only marked as consumed after the file has been successfully transferred to the client, preventing data loss on network interruptions. Additionally, added a `DecorateFiles` helper in the box store to reduce code duplication.
This commit is contained in:
@@ -75,6 +75,10 @@ func SetOneTimeDownloadExpiry(seconds int64) {
|
||||
oneTimeDownloadExpiry = seconds
|
||||
}
|
||||
|
||||
func OneTimeDownloadExpiry() int64 {
|
||||
return oneTimeDownloadExpiry
|
||||
}
|
||||
|
||||
func UploadRoot() string {
|
||||
return uploadRoot
|
||||
}
|
||||
@@ -185,12 +189,7 @@ func BoxSummary(boxID string) (models.BoxSummary, error) {
|
||||
|
||||
func ListFiles(boxID string) ([]models.BoxFile, error) {
|
||||
if manifest, err := reconcileManifest(boxID); err == nil && len(manifest.Files) > 0 {
|
||||
files := make([]models.BoxFile, 0, len(manifest.Files))
|
||||
for _, file := range manifest.Files {
|
||||
files = append(files, DecorateFile(boxID, file))
|
||||
}
|
||||
|
||||
return files, nil
|
||||
return DecorateFiles(boxID, manifest.Files), nil
|
||||
}
|
||||
|
||||
return listCompletedFilesFromDisk(boxID)
|
||||
@@ -513,6 +512,14 @@ func DecorateFile(boxID string, file models.BoxFile) models.BoxFile {
|
||||
return file
|
||||
}
|
||||
|
||||
func DecorateFiles(boxID string, files []models.BoxFile) []models.BoxFile {
|
||||
decorated := make([]models.BoxFile, 0, len(files))
|
||||
for _, file := range files {
|
||||
decorated = append(decorated, DecorateFile(boxID, file))
|
||||
}
|
||||
return decorated
|
||||
}
|
||||
|
||||
func IconForMimeType(mimeType string, filename string) string {
|
||||
extension := strings.ToLower(filepath.Ext(filename))
|
||||
|
||||
@@ -645,15 +652,13 @@ func startRetentionIfTerminalUnlocked(manifest *models.BoxManifest) {
|
||||
}
|
||||
|
||||
seconds := manifest.RetentionSecs
|
||||
if seconds <= 0 {
|
||||
if manifest.OneTimeDownload {
|
||||
seconds = oneTimeDownloadExpiry
|
||||
} else {
|
||||
seconds = normalizeRetentionOption(manifest.RetentionKey).Seconds
|
||||
}
|
||||
if manifest.OneTimeDownload {
|
||||
seconds = oneTimeDownloadExpiry
|
||||
} else if seconds <= 0 {
|
||||
seconds = normalizeRetentionOption(manifest.RetentionKey).Seconds
|
||||
}
|
||||
|
||||
if manifest.OneTimeDownload && seconds <= 0 {
|
||||
if seconds <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -663,8 +668,6 @@ func startRetentionIfTerminalUnlocked(manifest *models.BoxManifest) {
|
||||
}
|
||||
}
|
||||
|
||||
// seconds is already handled above
|
||||
|
||||
// Retention starts after uploads settle so slow or very large uploads do
|
||||
// not expire before users get a real chance to open the box.
|
||||
manifest.ExpiresAt = time.Now().UTC().Add(time.Duration(seconds) * time.Second)
|
||||
|
||||
Reference in New Issue
Block a user