Use AttachmentsV2 if the resumable upload link from V3 becomes corrupted.

This commit is contained in:
Alex Hart 2021-08-26 10:24:20 -03:00 committed by GitHub
parent ade6f60e76
commit 3f233ed39f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 5 deletions

View file

@ -32,6 +32,8 @@ import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException;
import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException;
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
@ -56,6 +58,7 @@ public final class AttachmentUploadJob extends BaseJob {
private static final String KEY_ROW_ID = "row_id";
private static final String KEY_UNIQUE_ID = "unique_id";
private static final String KEY_FORCE_V2 = "force_v2";
/**
* Foreground notification shows while uploading attachments above this.
@ -64,24 +67,29 @@ public final class AttachmentUploadJob extends BaseJob {
private final AttachmentId attachmentId;
private boolean forceV2;
public AttachmentUploadJob(AttachmentId attachmentId) {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
attachmentId);
attachmentId,
false);
}
private AttachmentUploadJob(@NonNull Job.Parameters parameters, @NonNull AttachmentId attachmentId) {
private AttachmentUploadJob(@NonNull Job.Parameters parameters, @NonNull AttachmentId attachmentId, boolean forceV2) {
super(parameters);
this.attachmentId = attachmentId;
this.forceV2 = forceV2;
}
@Override
public @NonNull Data serialize() {
return new Data.Builder().putLong(KEY_ROW_ID, attachmentId.getRowId())
.putLong(KEY_UNIQUE_ID, attachmentId.getUniqueId())
.putBoolean(KEY_FORCE_V2, forceV2)
.build();
}
@ -105,7 +113,10 @@ public final class AttachmentUploadJob extends BaseJob {
ResumableUploadSpec resumableUploadSpec;
if (inputData != null && inputData.hasString(ResumableUploadSpecJob.KEY_RESUME_SPEC)) {
if (forceV2) {
Log.d(TAG, "Forcing utilization of V2");
resumableUploadSpec = null;
} else if (inputData != null && inputData.hasString(ResumableUploadSpecJob.KEY_RESUME_SPEC)) {
Log.d(TAG, "Using attachments V3");
resumableUploadSpec = ResumableUploadSpec.deserialize(inputData.getString(ResumableUploadSpecJob.KEY_RESUME_SPEC));
} else {
@ -137,6 +148,11 @@ public final class AttachmentUploadJob extends BaseJob {
Attachment attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.getFastPreflightId()).get();
database.updateAttachmentAfterUpload(databaseAttachment.getAttachmentId(), attachment, remoteAttachment.getUploadTimestamp());
} catch (NonSuccessfulResumableUploadResponseCodeException e) {
if (e.getCode() == 400) {
Log.w(TAG, "Failed to upload due to a 400 when getting resumable upload information. Downgrading to attachments v2", e);
forceV2 = true;
}
}
}
@ -245,7 +261,7 @@ public final class AttachmentUploadJob extends BaseJob {
public static final class Factory implements Job.Factory<AttachmentUploadJob> {
@Override
public @NonNull AttachmentUploadJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
return new AttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)));
return new AttachmentUploadJob(parameters, new AttachmentId(data.getLong(KEY_ROW_ID), data.getLong(KEY_UNIQUE_ID)), data.getBooleanOrDefault(KEY_FORCE_V2, false));
}
}
}

View file

@ -0,0 +1,7 @@
package org.whispersystems.signalservice.api.push.exceptions;
public class NonSuccessfulResumableUploadResponseCodeException extends NonSuccessfulResponseCodeException {
public NonSuccessfulResumableUploadResponseCodeException(int code, String s) {
super(code, s);
}
}

View file

@ -59,6 +59,7 @@ import org.whispersystems.signalservice.api.push.exceptions.MalformedResponseExc
import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
import org.whispersystems.signalservice.api.push.exceptions.NoContentException;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException;
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
@ -1374,7 +1375,7 @@ public class PushServiceSocket {
} else if (response.code() == 404) {
throw new ResumeLocationInvalidException();
} else {
throw new NonSuccessfulResponseCodeException(response.code(), "Response: " + response);
throw new NonSuccessfulResumableUploadResponseCodeException(response.code(), "Response: " + response);
}
} finally {
synchronized (connections) {