Supply size to attachment form endpoint for archive backfill.

This commit is contained in:
Greyson Parrelli
2026-04-20 15:45:33 -04:00
committed by Alex Hart
parent bde1a94122
commit 7c147982c4
5 changed files with 30 additions and 6 deletions

View File

@@ -1690,10 +1690,10 @@ object BackupRepository {
*
* It's important to note that in order to get this to the archive cdn, you still need to use [copyAttachmentToArchive].
*/
fun getAttachmentUploadForm(): NetworkResult<AttachmentUploadForm> {
fun getAttachmentUploadForm(uploadLength: Long): NetworkResult<AttachmentUploadForm> {
return initBackupAndFetchAuth()
.then { credential ->
SignalNetwork.archive.getMediaUploadForm(SignalStore.account.requireAci(), credential.mediaBackupAccess)
SignalNetwork.archive.getMediaUploadForm(SignalStore.account.requireAci(), credential.mediaBackupAccess, uploadLength)
}
}

View File

@@ -31,8 +31,10 @@ import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.NetworkResult
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream
import org.whispersystems.signalservice.internal.push.AttachmentUploadForm
import java.io.ByteArrayInputStream
import java.io.IOException
@@ -176,7 +178,9 @@ class ArchiveThumbnailUploadJob private constructor(
return Result.failure()
}
val form: AttachmentUploadForm = when (val formResult = BackupRepository.getAttachmentUploadForm()) {
val ciphertextLength = AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(thumbnailResult.data.size.toLong()))
val form: AttachmentUploadForm = when (val formResult = BackupRepository.getAttachmentUploadForm(ciphertextLength)) {
is NetworkResult.Success -> formResult.result
is NetworkResult.ApplicationError -> {
Log.w(TAG, "Failed to get upload form due to an application error. Retrying.", formResult.throwable)
@@ -192,6 +196,13 @@ class ArchiveThumbnailUploadJob private constructor(
Log.w(TAG, "Rate limited when getting upload form.")
Result.retry(formResult.retryAfter()?.inWholeMilliseconds ?: defaultBackoff())
}
413 -> {
Log.w(TAG, "Thumbnail is too large to upload to the archive. Marking as a permanent failure.")
ArchiveDatabaseExecutor.runBlocking {
SignalDatabase.attachments.setArchiveThumbnailTransferState(attachmentId, AttachmentTable.ArchiveTransferState.PERMANENT_FAILURE)
}
Result.failure()
}
else -> {
Log.w(TAG, "Failed to get upload form with status code ${formResult.code}")
Result.retry(defaultBackoff())

View File

@@ -36,9 +36,11 @@ import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.NetworkResult
import org.whispersystems.signalservice.api.archive.ArchiveMediaUploadFormStatusCodes
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
import org.whispersystems.signalservice.api.messages.AttachmentTransferProgress
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment
import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream
import org.whispersystems.signalservice.internal.push.AttachmentUploadForm
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec
import java.io.FileNotFoundException
@@ -230,8 +232,10 @@ class UploadAttachmentToArchiveJob private constructor(
val existingSpec = uploadSpec?.let { ResumableUploadSpec.from(it) }
val ciphertextLength = AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(attachment.size))
val form: AttachmentUploadForm? = if (existingSpec == null) {
when (val formResult = BackupRepository.getAttachmentUploadForm()) {
when (val formResult = BackupRepository.getAttachmentUploadForm(ciphertextLength)) {
is NetworkResult.Success -> formResult.result
is NetworkResult.ApplicationError -> {
Log.w(TAG, "[$attachmentId]$mediaIdLog Failed to get upload form due to an application error.", formResult.throwable)
@@ -248,6 +252,13 @@ class UploadAttachmentToArchiveJob private constructor(
Log.w(TAG, "[$attachmentId]$mediaIdLog Rate limited when getting upload form.")
Result.retry(formResult.retryAfter()?.inWholeMilliseconds ?: defaultBackoff())
}
ArchiveMediaUploadFormStatusCodes.MediaTooLarge -> {
Log.w(TAG, "[$attachmentId]$mediaIdLog Media is too large to upload to the archive. Marking as a permanent failure.")
ArchiveDatabaseExecutor.runBlocking {
setArchiveTransferStateWithDelayedNotification(attachmentId, AttachmentTable.ArchiveTransferState.PERMANENT_FAILURE)
}
Result.failure()
}
else -> Result.retry(defaultBackoff())
}
}