Search in sources :

Example 1 with NonSuccessfulResumableUploadResponseCodeException

use of org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException in project Signal-Android by WhisperSystems.

the class AttachmentUploadJob method onRun.

@Override
public void onRun() throws Exception {
    if (!Recipient.self().isRegistered()) {
        throw new NotPushRegisteredException();
    }
    Data inputData = getInputData();
    ResumableUploadSpec resumableUploadSpec;
    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 {
        Log.d(TAG, "Using attachments V2");
        resumableUploadSpec = null;
    }
    SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
    AttachmentDatabase database = SignalDatabase.attachments();
    DatabaseAttachment databaseAttachment = database.getAttachment(attachmentId);
    if (databaseAttachment == null) {
        throw new InvalidAttachmentException("Cannot find the specified attachment.");
    }
    long timeSinceUpload = System.currentTimeMillis() - databaseAttachment.getUploadTimestamp();
    if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.getLocation())) {
        Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded " + timeSinceUpload + " ms ago. Skipping.");
        return;
    } else if (databaseAttachment.getUploadTimestamp() > 0) {
        Log.i(TAG, "This file was previously-uploaded, but too long ago to be re-used. Age: " + timeSinceUpload + " ms");
    }
    Log.i(TAG, "Uploading attachment for message " + databaseAttachment.getMmsId() + " with ID " + databaseAttachment.getAttachmentId());
    try (NotificationController notification = getNotificationForAttachment(databaseAttachment)) {
        SignalServiceAttachment localAttachment = getAttachmentFor(databaseAttachment, notification, resumableUploadSpec);
        SignalServiceAttachmentPointer remoteAttachment = messageSender.uploadAttachment(localAttachment.asStream());
        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;
        }
    }
}
Also used : NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) Data(org.thoughtcrime.securesms.jobmanager.Data) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) NonSuccessfulResumableUploadResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) ResumableUploadSpec(org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec) NotificationController(org.thoughtcrime.securesms.service.NotificationController)

Example 2 with NonSuccessfulResumableUploadResponseCodeException

use of org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException in project Signal-Android by signalapp.

the class AttachmentUploadJob method onRun.

@Override
public void onRun() throws Exception {
    if (!Recipient.self().isRegistered()) {
        throw new NotPushRegisteredException();
    }
    Data inputData = getInputData();
    ResumableUploadSpec resumableUploadSpec;
    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 {
        Log.d(TAG, "Using attachments V2");
        resumableUploadSpec = null;
    }
    SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
    AttachmentDatabase database = SignalDatabase.attachments();
    DatabaseAttachment databaseAttachment = database.getAttachment(attachmentId);
    if (databaseAttachment == null) {
        throw new InvalidAttachmentException("Cannot find the specified attachment.");
    }
    long timeSinceUpload = System.currentTimeMillis() - databaseAttachment.getUploadTimestamp();
    if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD && !TextUtils.isEmpty(databaseAttachment.getLocation())) {
        Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded " + timeSinceUpload + " ms ago. Skipping.");
        return;
    } else if (databaseAttachment.getUploadTimestamp() > 0) {
        Log.i(TAG, "This file was previously-uploaded, but too long ago to be re-used. Age: " + timeSinceUpload + " ms");
    }
    Log.i(TAG, "Uploading attachment for message " + databaseAttachment.getMmsId() + " with ID " + databaseAttachment.getAttachmentId());
    try (NotificationController notification = getNotificationForAttachment(databaseAttachment)) {
        SignalServiceAttachment localAttachment = getAttachmentFor(databaseAttachment, notification, resumableUploadSpec);
        SignalServiceAttachmentPointer remoteAttachment = messageSender.uploadAttachment(localAttachment.asStream());
        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;
        }
    }
}
Also used : NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) Data(org.thoughtcrime.securesms.jobmanager.Data) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) NonSuccessfulResumableUploadResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) ResumableUploadSpec(org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec) NotificationController(org.thoughtcrime.securesms.service.NotificationController)

Example 3 with NonSuccessfulResumableUploadResponseCodeException

use of org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException in project Signal-Android by WhisperSystems.

the class PushServiceSocket method getResumeInfo.

private ResumeInfo getResumeInfo(String resumableUrl, long contentLength) throws IOException {
    ConnectionHolder connectionHolder = getRandom(cdnClientsMap.get(2), random);
    OkHttpClient okHttpClient = connectionHolder.getClient().newBuilder().connectTimeout(soTimeoutMillis, TimeUnit.MILLISECONDS).readTimeout(soTimeoutMillis, TimeUnit.MILLISECONDS).build();
    final long offset;
    final String contentRange;
    Request.Builder request = new Request.Builder().url(buildConfiguredUrl(connectionHolder, resumableUrl)).put(RequestBody.create(null, "")).addHeader("Content-Range", String.format(Locale.US, "bytes */%d", contentLength));
    if (connectionHolder.getHostHeader().isPresent()) {
        request.header("host", connectionHolder.getHostHeader().get());
    }
    Call call = okHttpClient.newCall(request.build());
    synchronized (connections) {
        connections.add(call);
    }
    try {
        Response response;
        try {
            response = call.execute();
        } catch (IOException e) {
            throw new PushNetworkException(e);
        }
        if (response.isSuccessful()) {
            offset = contentLength;
            contentRange = null;
        } else if (response.code() == 308) {
            String rangeCompleted = response.header("Range");
            if (rangeCompleted == null) {
                offset = 0;
            } else {
                offset = Long.parseLong(rangeCompleted.split("-")[1]) + 1;
            }
            contentRange = String.format(Locale.US, "bytes %d-%d/%d", offset, contentLength - 1, contentLength);
        } else if (response.code() == 404) {
            throw new ResumeLocationInvalidException();
        } else {
            throw new NonSuccessfulResumableUploadResponseCodeException(response.code(), "Response: " + response);
        }
    } finally {
        synchronized (connections) {
            connections.remove(call);
        }
    }
    return new ResumeInfo(contentRange, offset);
}
Also used : Call(okhttp3.Call) OkHttpClient(okhttp3.OkHttpClient) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) ReceiptCredentialRequest(org.signal.zkgroup.receipts.ReceiptCredentialRequest) Request(okhttp3.Request) ChangePhoneNumberRequest(org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest) DiscoveryRequest(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest) KeyBackupRequest(org.whispersystems.signalservice.internal.contacts.entities.KeyBackupRequest) ProfileKeyCredentialRequest(org.signal.zkgroup.profiles.ProfileKeyCredentialRequest) GroupsV2AuthorizationString(org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString) IOException(java.io.IOException) NonSuccessfulResumableUploadResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException) CallingResponse(org.whispersystems.signalservice.api.messages.calls.CallingResponse) Response(okhttp3.Response) KeyBackupResponse(org.whispersystems.signalservice.internal.contacts.entities.KeyBackupResponse) ReceiptCredentialResponse(org.signal.zkgroup.receipts.ReceiptCredentialResponse) CredentialResponse(org.whispersystems.signalservice.api.groupsv2.CredentialResponse) StorageAuthResponse(org.whispersystems.signalservice.api.storage.StorageAuthResponse) VerifyDeviceResponse(org.whispersystems.signalservice.api.messages.multidevice.VerifyDeviceResponse) DiscoveryResponse(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryResponse) ProfileKeyCredentialResponse(org.signal.zkgroup.profiles.ProfileKeyCredentialResponse) TokenResponse(org.whispersystems.signalservice.internal.contacts.entities.TokenResponse) ResumeLocationInvalidException(org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException)

Example 4 with NonSuccessfulResumableUploadResponseCodeException

use of org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException in project Signal-Android by signalapp.

the class PushServiceSocket method getResumeInfo.

private ResumeInfo getResumeInfo(String resumableUrl, long contentLength) throws IOException {
    ConnectionHolder connectionHolder = getRandom(cdnClientsMap.get(2), random);
    OkHttpClient okHttpClient = connectionHolder.getClient().newBuilder().connectTimeout(soTimeoutMillis, TimeUnit.MILLISECONDS).readTimeout(soTimeoutMillis, TimeUnit.MILLISECONDS).build();
    final long offset;
    final String contentRange;
    Request.Builder request = new Request.Builder().url(buildConfiguredUrl(connectionHolder, resumableUrl)).put(RequestBody.create(null, "")).addHeader("Content-Range", String.format(Locale.US, "bytes */%d", contentLength));
    if (connectionHolder.getHostHeader().isPresent()) {
        request.header("host", connectionHolder.getHostHeader().get());
    }
    Call call = okHttpClient.newCall(request.build());
    synchronized (connections) {
        connections.add(call);
    }
    try {
        Response response;
        try {
            response = call.execute();
        } catch (IOException e) {
            throw new PushNetworkException(e);
        }
        if (response.isSuccessful()) {
            offset = contentLength;
            contentRange = null;
        } else if (response.code() == 308) {
            String rangeCompleted = response.header("Range");
            if (rangeCompleted == null) {
                offset = 0;
            } else {
                offset = Long.parseLong(rangeCompleted.split("-")[1]) + 1;
            }
            contentRange = String.format(Locale.US, "bytes %d-%d/%d", offset, contentLength - 1, contentLength);
        } else if (response.code() == 404) {
            throw new ResumeLocationInvalidException();
        } else {
            throw new NonSuccessfulResumableUploadResponseCodeException(response.code(), "Response: " + response);
        }
    } finally {
        synchronized (connections) {
            connections.remove(call);
        }
    }
    return new ResumeInfo(contentRange, offset);
}
Also used : Call(okhttp3.Call) OkHttpClient(okhttp3.OkHttpClient) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) ReceiptCredentialRequest(org.signal.zkgroup.receipts.ReceiptCredentialRequest) Request(okhttp3.Request) ChangePhoneNumberRequest(org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest) DiscoveryRequest(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryRequest) KeyBackupRequest(org.whispersystems.signalservice.internal.contacts.entities.KeyBackupRequest) ProfileKeyCredentialRequest(org.signal.zkgroup.profiles.ProfileKeyCredentialRequest) GroupsV2AuthorizationString(org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString) IOException(java.io.IOException) NonSuccessfulResumableUploadResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException) CallingResponse(org.whispersystems.signalservice.api.messages.calls.CallingResponse) Response(okhttp3.Response) KeyBackupResponse(org.whispersystems.signalservice.internal.contacts.entities.KeyBackupResponse) ReceiptCredentialResponse(org.signal.zkgroup.receipts.ReceiptCredentialResponse) CredentialResponse(org.whispersystems.signalservice.api.groupsv2.CredentialResponse) StorageAuthResponse(org.whispersystems.signalservice.api.storage.StorageAuthResponse) VerifyDeviceResponse(org.whispersystems.signalservice.api.messages.multidevice.VerifyDeviceResponse) DiscoveryResponse(org.whispersystems.signalservice.internal.contacts.entities.DiscoveryResponse) ProfileKeyCredentialResponse(org.signal.zkgroup.profiles.ProfileKeyCredentialResponse) TokenResponse(org.whispersystems.signalservice.internal.contacts.entities.TokenResponse) ResumeLocationInvalidException(org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException)

Aggregations

NonSuccessfulResumableUploadResponseCodeException (org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResumableUploadResponseCodeException)4 IOException (java.io.IOException)2 Call (okhttp3.Call)2 OkHttpClient (okhttp3.OkHttpClient)2 Request (okhttp3.Request)2 Response (okhttp3.Response)2 ProfileKeyCredentialRequest (org.signal.zkgroup.profiles.ProfileKeyCredentialRequest)2 ProfileKeyCredentialResponse (org.signal.zkgroup.profiles.ProfileKeyCredentialResponse)2 ReceiptCredentialRequest (org.signal.zkgroup.receipts.ReceiptCredentialRequest)2 ReceiptCredentialResponse (org.signal.zkgroup.receipts.ReceiptCredentialResponse)2 Attachment (org.thoughtcrime.securesms.attachments.Attachment)2 DatabaseAttachment (org.thoughtcrime.securesms.attachments.DatabaseAttachment)2 PointerAttachment (org.thoughtcrime.securesms.attachments.PointerAttachment)2 AttachmentDatabase (org.thoughtcrime.securesms.database.AttachmentDatabase)2 Data (org.thoughtcrime.securesms.jobmanager.Data)2 NotPushRegisteredException (org.thoughtcrime.securesms.net.NotPushRegisteredException)2 NotificationController (org.thoughtcrime.securesms.service.NotificationController)2 SignalServiceMessageSender (org.whispersystems.signalservice.api.SignalServiceMessageSender)2 ChangePhoneNumberRequest (org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest)2 CredentialResponse (org.whispersystems.signalservice.api.groupsv2.CredentialResponse)2