@@ -55,6 +55,50 @@ class TusUploadHelper(
5555 cancelled = false
5656 Timber .d(" TUS: starting upload for %s size=%d" , remotePath, fileSize)
5757
58+ val (resolvedTusUrl, createdOffset) = prepareUpload(
59+ client = client,
60+ transfer = transfer,
61+ uploadId = uploadId,
62+ localPath = localPath,
63+ remotePath = remotePath,
64+ fileSize = fileSize,
65+ mimeType = mimeType,
66+ lastModified = lastModified,
67+ spaceWebDavUrl = spaceWebDavUrl
68+ )
69+
70+ val offset = fetchCurrentOffset(client, resolvedTusUrl, createdOffset)
71+ Timber .d(" TUS: resume offset %d / %d" , offset, fileSize)
72+ progressCallback?.invoke(offset, fileSize)
73+
74+ val (finalOffset, finalEtag) = performUploadLoop(
75+ client = client,
76+ resolvedTusUrl = resolvedTusUrl,
77+ localPath = localPath,
78+ fileSize = fileSize,
79+ tusSupport = tusSupport,
80+ progressListener = progressListener,
81+ progressCallback = progressCallback,
82+ initialOffset = offset,
83+ uploadId = uploadId,
84+ )
85+
86+ verifyUploadCompletion(finalOffset, fileSize, uploadId)
87+
88+ return finalizeEtag(client, remotePath, spaceWebDavUrl, finalEtag, fileSize)
89+ }
90+
91+ private fun prepareUpload (
92+ client : OpenCloudClient ,
93+ transfer : OCTransfer ,
94+ uploadId : Long ,
95+ localPath : String ,
96+ remotePath : String ,
97+ fileSize : Long ,
98+ mimeType : String ,
99+ lastModified : String? ,
100+ spaceWebDavUrl : String?
101+ ): Pair <String , Long ?> {
58102 var tusUrl = transfer.tusUploadUrl
59103 val checksumHex = transfer.tusUploadChecksum?.substringAfter(" sha256:" )
60104 var createdOffset: Long? = null
@@ -116,40 +160,30 @@ class TusUploadHelper(
116160 }
117161
118162 val resolvedTusUrl = tusUrl ? : throw IllegalStateException (" TUS: missing upload URL for $remotePath " )
163+ return Pair (resolvedTusUrl, createdOffset)
164+ }
119165
120- var offset = if (createdOffset != null ) {
121- createdOffset
122- } else {
123- try {
124- executeRemoteOperation {
125- GetTusUploadOffsetRemoteOperation (resolvedTusUrl).execute(client)
126- }
127- } catch (e: java.io.IOException ) {
128- Timber .w(e, " TUS: failed to fetch current offset" )
129- throw e
130- } catch (e: Throwable ) {
131- Timber .w(e, " TUS: failed to fetch current offset" )
132- 0L
166+ private fun fetchCurrentOffset (
167+ client : OpenCloudClient ,
168+ resolvedTusUrl : String ,
169+ createdOffset : Long?
170+ ): Long = if (createdOffset != null ) {
171+ createdOffset
172+ } else {
173+ try {
174+ executeRemoteOperation {
175+ GetTusUploadOffsetRemoteOperation (resolvedTusUrl).execute(client)
133176 }
134- }.coerceAtLeast(0L )
135- Timber .d(" TUS: resume offset %d / %d" , offset, fileSize)
136- progressCallback?.invoke(offset, fileSize)
137-
138- val loopResult = performUploadLoop(
139- client = client,
140- resolvedTusUrl = resolvedTusUrl,
141- localPath = localPath,
142- fileSize = fileSize,
143- tusSupport = tusSupport,
144- progressListener = progressListener,
145- progressCallback = progressCallback,
146- initialOffset = offset,
147- uploadId = uploadId,
148- )
149- offset = loopResult.first
150- val finalEtag = loopResult.second
177+ } catch (e: java.io.IOException ) {
178+ Timber .w(e, " TUS: failed to fetch current offset" )
179+ throw e
180+ } catch (e: Throwable ) {
181+ Timber .w(e, " TUS: failed to fetch current offset" )
182+ 0L
183+ }
184+ }.coerceAtLeast(0L )
151185
152- // Verify upload is actually complete
186+ private fun verifyUploadCompletion ( offset : Long , fileSize : Long , uploadId : Long ) {
153187 if (offset != fileSize) {
154188 Timber .e(" TUS: upload loop exited but offset=%d != fileSize=%d" , offset, fileSize)
155189 throw java.io.IOException (" TUS: upload incomplete - offset $offset does not match file size $fileSize " )
@@ -164,8 +198,15 @@ class TusUploadHelper(
164198 tusUploadExpires = null ,
165199 tusUploadConcat = null ,
166200 )
167- // If TUS PATCH didn't return an ETag (which is normal for openCloud's TUS implementation),
168- // fetch it via a PROPFIND request on the newly uploaded file.
201+ }
202+
203+ private fun finalizeEtag (
204+ client : OpenCloudClient ,
205+ remotePath : String ,
206+ spaceWebDavUrl : String? ,
207+ finalEtag : String? ,
208+ fileSize : Long
209+ ): String? {
169210 var resultEtag = finalEtag
170211 if (resultEtag.isNullOrBlank()) {
171212 Timber .d(" TUS: no etag from PATCH, attempting PROPFIND for %s (spaceWebDavUrl=%s)" , remotePath, spaceWebDavUrl)
0 commit comments