Skip to content

Commit 573812e

Browse files
committed
Uploads: Send OC-Checksum for non-TUS
1 parent dbe26b4 commit 573812e

6 files changed

Lines changed: 33 additions & 12 deletions

File tree

opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromContentUriWorker.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -377,12 +377,16 @@ class UploadFileFromContentUriWorker(
377377
tusUploadUrl = ocTransfer.tusUploadUrl,
378378
)
379379

380+
if (hasPendingTusSession && !hasStoredSha1Checksum()) {
381+
Timber.w("TUS session for %s has no original checksum. Clearing state and recreating.", uploadPath)
382+
clearTusState()
383+
}
384+
// Always have the whole-file checksum: TUS sends it in Upload-Metadata, plain PUTs
385+
// in the OC-Checksum header. Usually already persisted by copyFileToLocalStorage;
386+
// this only reads the source again for cache-reuse runs of pre-checksum DB rows.
387+
ensureOriginalTusChecksum()
388+
380389
if (shouldTryTus) {
381-
if (hasPendingTusSession && !hasStoredSha1Checksum()) {
382-
Timber.w("TUS session for %s has no original checksum. Clearing state and recreating.", uploadPath)
383-
clearTusState()
384-
}
385-
ensureOriginalTusChecksum()
386390
Timber.d(
387391
"Attempting TUS upload (size=%d, threshold=%d, resume=%s)",
388392
fileSize,
@@ -434,13 +438,15 @@ class UploadFileFromContentUriWorker(
434438
}
435439

436440
private fun uploadPlainFile(client: OpenCloudClient) {
441+
val fileChecksum = TusChecksumHelper.parseStoredChecksum(ocTransfer.tusUploadChecksum)
437442
uploadFileOperation = UploadFileFromFileSystemOperation(
438443
localPath = cachePath,
439444
remotePath = uploadPath,
440445
mimeType = mimeType,
441446
lastModifiedTimestamp = lastModified,
442447
requiredEtag = null,
443448
spaceWebDavUrl = spaceWebDavUrl,
449+
ocChecksum = fileChecksum?.ocChecksumHeaderValue,
444450
).apply {
445451
addDataTransferProgressListener(this@UploadFileFromContentUriWorker)
446452
}

opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromFileSystemWorker.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,15 @@ class UploadFileFromFileSystemWorker(
267267
tusUploadUrl = ocTransfer.tusUploadUrl,
268268
)
269269

270+
if (hasPendingTusSession && !hasStoredSha1Checksum()) {
271+
Timber.w("TUS session for %s has no original checksum. Clearing state and recreating.", uploadPath)
272+
clearTusState()
273+
}
274+
// Always compute the whole-file checksum: TUS sends it in Upload-Metadata,
275+
// plain PUTs send it in the OC-Checksum header.
276+
ensureOriginalTusChecksum()
277+
270278
if (shouldTryTus) {
271-
if (hasPendingTusSession && !hasStoredSha1Checksum()) {
272-
Timber.w("TUS session for %s has no original checksum. Clearing state and recreating.", uploadPath)
273-
clearTusState()
274-
}
275-
ensureOriginalTusChecksum()
276279
Timber.d(
277280
"Attempting TUS upload (size=%d, threshold=%d, resume=%s)",
278281
fileSize,
@@ -326,13 +329,15 @@ class UploadFileFromFileSystemWorker(
326329
}
327330

328331
private fun uploadPlainFile(client: OpenCloudClient) {
332+
val fileChecksum = TusChecksumHelper.parseStoredChecksum(ocTransfer.tusUploadChecksum)
329333
uploadFileOperation = UploadFileFromFileSystemOperation(
330334
localPath = fileSystemPath,
331335
remotePath = uploadPath,
332336
mimeType = mimetype,
333337
lastModifiedTimestamp = lastModified,
334338
requiredEtag = eTagInConflict,
335339
spaceWebDavUrl = spaceWebDavUrl,
340+
ocChecksum = fileChecksum?.ocChecksumHeaderValue,
336341
).apply {
337342
addDataTransferProgressListener(this@UploadFileFromFileSystemWorker)
338343
}

opencloudComLibrary/src/main/java/eu/opencloud/android/lib/common/http/HttpConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public class HttpConstants {
4444
public static final String CONTENT_LENGTH_HEADER = "Content-Length";
4545
public static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length";
4646
public static final String OC_X_OC_MTIME_HEADER = "X-OC-Mtime";
47+
public static final String OC_CHECKSUM_HEADER = "OC-Checksum";
4748
public static final String OC_X_REQUEST_ID = "X-Request-ID";
4849
public static final String X_HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override";
4950
public static final String LOCATION_HEADER = "Location";

opencloudComLibrary/src/main/java/eu/opencloud/android/lib/resources/files/DownloadRemoteFileOperation.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ class DownloadRemoteFileOperation(
6969
return try {
7070
tmpFile.parentFile?.mkdirs()
7171
downloadFile(client, tmpFile).also { result ->
72-
Timber.i("Download of $remotePath to $tmpPath: ${result.logMessage}")
72+
val outcome = if (result.isSuccess) "success, etag=$etag" else result.logMessage
73+
Timber.i("Download of $remotePath to $tmpPath: $outcome")
7374
}
7475
} catch (e: Exception) {
7576
RemoteOperationResult<Unit>(e).also { result ->

opencloudComLibrary/src/main/java/eu/opencloud/android/lib/resources/files/UploadFileFromFileSystemOperation.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ open class UploadFileFromFileSystemOperation(
5757
val lastModifiedTimestamp: String,
5858
val requiredEtag: String?,
5959
val spaceWebDavUrl: String? = null,
60+
/** Whole-file checksum as "ALGORITHM:hex" (e.g. "SHA1:30338d…"); server rejects with 400 on mismatch. */
61+
val ocChecksum: String? = null,
6062
) : RemoteOperation<Unit>() {
6163

6264
protected val cancellationRequested = AtomicBoolean(false)
@@ -76,7 +78,8 @@ open class UploadFileFromFileSystemOperation(
7678
} else {
7779
// perform the upload
7880
result = uploadFile(client)
79-
Timber.i("Upload of $localPath to $remotePath: ${result.logMessage}")
81+
val outcome = if (result.isSuccess) "success, etag=$etag" else result.logMessage
82+
Timber.i("Upload of $localPath to $remotePath: $outcome")
8083
}
8184
} catch (e: Exception) {
8285
if (putMethod?.isAborted == true) {
@@ -107,6 +110,7 @@ open class UploadFileFromFileSystemOperation(
107110
}
108111
addRequestHeader(HttpConstants.OC_TOTAL_LENGTH_HEADER, fileToUpload.length().toString())
109112
addRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER, lastModifiedTimestamp)
113+
ocChecksum?.let { addRequestHeader(HttpConstants.OC_CHECKSUM_HEADER, it) }
110114
}
111115

112116
val status = client.executeHttpMethod(putMethod)

opencloudComLibrary/src/main/java/eu/opencloud/android/lib/resources/files/tus/TusChecksumHelper.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ object TusChecksumHelper {
4848
val uploadAlgorithm: String
4949
get() = algorithm.lowercase(Locale.ROOT)
5050

51+
/** Value for the OC-Checksum header on plain PUTs: "SHA1:<hex>" (colon-separated). */
52+
val ocChecksumHeaderValue: String
53+
get() = "${metadataAlgorithm()}:${hex.lowercase(Locale.ROOT)}"
54+
5155
private fun metadataAlgorithm(): String =
5256
if (algorithm.lowercase(Locale.ROOT) == SHA1_WIRE_ALGORITHM) SHA1_METADATA_ALGORITHM
5357
else algorithm.uppercase(Locale.ROOT)

0 commit comments

Comments
 (0)