Skip to content

Commit 2e64f89

Browse files
authored
Merge pull request #3656 from SpiritCroc/broken_downloads
Avoid incomplete downloads in cache
2 parents f517691 + 512e1b3 commit 2e64f89

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

changelog.d/3656.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Avoid incomplete downloads in cache

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt

+14-2
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,14 @@ internal class DefaultFileService @Inject constructor(
131131
Timber.v("Response size ${response.body?.contentLength()} - Stream available: ${!source.exhausted()}")
132132

133133
// Write the file to cache (encrypted version if the file is encrypted)
134-
writeToFile(source.inputStream(), cachedFiles.file)
134+
// Write to a tmp file first, so if we abort before done, we don't have a broken cached file
135+
val tmpFile = File(cachedFiles.file.parentFile, "${cachedFiles.file.name}.tmp")
136+
if (tmpFile.exists()) {
137+
Timber.v("## FileService: discard aborted tmp file ${tmpFile.path}")
138+
}
139+
writeToFile(source.inputStream(), tmpFile)
135140
response.close()
141+
tmpFile.renameTo(cachedFiles.file)
136142
} else {
137143
Timber.v("## FileService: cache hit for $url")
138144
}
@@ -145,15 +151,21 @@ internal class DefaultFileService @Inject constructor(
145151
Timber.v("## FileService: decrypt file")
146152
// Ensure the parent folder exists
147153
cachedFiles.decryptedFile.parentFile?.mkdirs()
154+
// Write to a tmp file first, so if we abort before done, we don't have a broken cached file
155+
val tmpFile = File(cachedFiles.decryptedFile.parentFile, "${cachedFiles.decryptedFile.name}.tmp")
156+
if (tmpFile.exists()) {
157+
Timber.v("## FileService: discard aborted tmp file ${tmpFile.path}")
158+
}
148159
val decryptSuccess = cachedFiles.file.inputStream().use { inputStream ->
149-
cachedFiles.decryptedFile.outputStream().buffered().use { outputStream ->
160+
tmpFile.outputStream().buffered().use { outputStream ->
150161
MXEncryptedAttachments.decryptAttachment(
151162
inputStream,
152163
elementToDecrypt,
153164
outputStream
154165
)
155166
}
156167
}
168+
tmpFile.renameTo(cachedFiles.decryptedFile)
157169
if (!decryptSuccess) {
158170
throw IllegalStateException("Decryption error")
159171
}

0 commit comments

Comments
 (0)