Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Text (.txt) file won't download / open in Android App #4352

Closed
geobzmm opened this issue Mar 27, 2024 · 89 comments · Fixed by #4415
Closed

[BUG] Text (.txt) file won't download / open in Android App #4352

geobzmm opened this issue Mar 27, 2024 · 89 comments · Fixed by #4415

Comments

@geobzmm
Copy link

geobzmm commented Mar 27, 2024

Actual behaviour

Creating a .txt file on another device containing a few words or some notes in a accessible folder then syncs as expected to all devices - server, laptop, desktop and Mobile / Cell. the .txt file can be opened / viewed on server, laptop (win 10), desktop (win 11) but Android App displays message "Download Failed". All other "document" formats appear to work fine (eg. .pdf, .docx, .xlsx, .doc etc...).

Expected behaviour

The .txt file should open and show the text in the file or be downloadable to the Android device (neither of which is possible).

Steps to reproduce

  1. Create .txt file containing text such as "Hello World!".
  2. Allow to sync to OwnCloud Server - this works when file is originally generated on PC.
  3. Refresh folder on Android device and attempt to open / download file.
  4. Message appears onscreen "Download Failed".

Can this problem be reproduced with the official owncloud server?
(url: https://demo.owncloud.org, user: test, password: test)
Not tested on Official Server

Environment data

Android version: v13

Device model: Samsung Galaxy S20+5G

Stock or customized system: Stock One UI v5.1

ownCloud app version: v4.2.1

ownCloud server version: Infinite Scale Community v4.0.3 running webclient v7.1.2

Logs

ownCloud App Log (data/owncloud.log)

D: 2024-03-27 20:28:32:819(SingleSessionManager.java:98)getClientFor starting 
V: 2024-03-27 20:28:32:819(SingleSessionManager.java:125)reusing client for account [OwnCloudServer]
D: 2024-03-27 20:28:32:820(SingleSessionManager.java:180)getClientFor finishing 
D: 2024-03-27 20:28:32:869(OwnCloudClient.java:129)Executing in request with id ff931731-xxx-etc
I: 2024-03-27 20:28:32:869(ReadRemoteFileOperation.kt:72)Read remote file /Basic Files/Another Text File.txt with status 207
I: 2024-03-27 20:28:32:871(SynchronizeFileUseCase.kt:66)File Another Text File.txt is not downloaded. Let's download it
I: 2024-03-27 20:28:32:875(DownloadFileUseCase.kt:103)Download of Another Text File.txt has been enqueued.
D: 2024-03-27 20:28:32:876(ViewModelExt.kt:68)Use case executed: SynchronizeFileUseCase with result: Success(data=DownloadEnqueued(workerId=d04d033c-xxxx-4833-b2c2-xxx))
D: 2024-03-27 20:28:32:912(GetRemoteAppRegistryOperation.kt:54)Successful response {"mime-types":[]}
D: 2024-03-27 20:28:32:917(GetRemoteAppRegistryOperation.kt:64)Get AppRegistry completed and parsed to AppRegistryResponse(value=[])
D: 2024-03-27 20:28:32:962(SingleSessionManager.java:98)getClientFor starting 
V: 2024-03-27 20:28:32:963(SingleSessionManager.java:125)reusing client for account [OwnCloudServer]
D: 2024-03-27 20:28:32:964(SingleSessionManager.java:180)getClientFor finishing 
D: 2024-03-27 20:28:32:965(OwnCloudClient.java:129)Executing in request with id dc4b9aca-xxxx-4dbb-a919-xxx
D: 2024-03-27 20:28:33:073(OwnCloudClient.java:129)Executing in request with id eb935ee4-xxxx-4178-8530-xxx
E: 2024-03-27 20:28:33:228(DownloadRemoteFileOperation.kt:154)Content-Length not equal to transferred bytes.
D: 2024-03-27 20:28:33:229(DownloadRemoteFileOperation.kt:155)totalToTransfer = 0, transferred = 2451
I: 2024-03-27 20:28:33:231(DownloadRemoteFileOperation.kt:80)Download of /Basic Files/Another Text File.txt to /data/user/0/com.owncloud.android/files/owncloud/tmp/[OwnCloudServer]/80630633-xxxx-4b45-a280-bd1e9c8d8eec$b22ee417-b5ce-xxxx-920e-xxxx/Basic Files/Another Text File.txt - HTTP status code: 207
E: 2024-03-27 20:28:33:236(DownloadFileWorker.kt:127)com.owncloud.android.domain.exceptions.LocalStorageNotMovedException
	at com.owncloud.android.workers.DownloadFileWorker.moveTemporalFileToFinalLocation(DownloadFileWorker.kt:200)
	at com.owncloud.android.workers.DownloadFileWorker.doWork(DownloadFileWorker.kt:123)
	at androidx.work.CoroutineWorker$startWork$1.invokeSuspend(CoroutineWorker.kt:68)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
@JuancaG05
Copy link
Collaborator

Hi @geobzmm! Thanks a lot for the info! We'll take a look ASAP and will let you know news about this in this thread 🍻

@chaotix-
Copy link

I have the exact same problem with four different devices and v4.2.1 (I downgraded one to v4.2.0, but this did not make a difference), but with all tested data types (*.ogg, *.txt, *.jpg)

D: 2024-04-20 01:13:34:511(OwnCloudClient.java:129)Executing in request with id 76fe8527-57eb-4255-bdbe-cfcb14c67f72
E: 2024-04-20 01:13:35:911(DownloadRemoteFileOperation.kt:154)Content-Length not equal to transferred bytes.
D: 2024-04-20 01:13:35:913(DownloadRemoteFileOperation.kt:155)totalToTransfer = 0, transferred = 3198389
I: 2024-04-20 01:13:35:919(DownloadRemoteFileOperation.kt:80)Download of /testfile.ogg to /data/user/0/com.owncloud.android/files/owncloud/tmp/xxx@xxx/testfile.ogg - HTTP status code: 207
E: 2024-04-20 01:13:35:921(DownloadFileWorker.kt:127)com.owncloud.android.domain.exceptions.LocalStorageNotMovedException
        at com.owncloud.android.workers.DownloadFileWorker.moveTemporalFileToFinalLocation(DownloadFileWorker.kt:200)
        at com.owncloud.android.workers.DownloadFileWorker.doWork(DownloadFileWorker.kt:123)
        at androidx.work.CoroutineWorker$startWork$1.invokeSuspend(CoroutineWorker.kt:68)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)

Webfrontend and Desktop-Sync are working fine.

This makes the Owncloud-App completely unusable for me.

@jesmrec
Copy link
Collaborator

jesmrec commented Apr 24, 2024

will do a look here. Meanwhile, you can use the "open with" option to open with 3rd party apps (changes will sync to the server as well)

@chaotix-
Copy link

Thank you for taking your time to look at this.

Unfortunately using "open with" does not work either. I get the same small popup "Herunterladen fehlgeschlagen" (Download failed) at the bottom of the screen before it asks what app I want to open the file with.

Let me know if I can assist you in any way with debugging this.

@Aitorbp Aitorbp added this to the 4.3 - Current milestone Apr 26, 2024
@Noni006
Copy link

Noni006 commented Apr 29, 2024

Hello,
Same probleme for me:
I: 2024-04-29 08:38:47:680(DownloadRemoteFileOperation.kt:80)Download of /test.pdf to /data/user/0/com.owncloud.android/files/owncloud/tmp/xxx@xxxx/test.pdf - HTTP status code: 207
E: 2024-04-29 08:38:47:682(DownloadFileWorker.kt:127)com.owncloud.android.domain.exceptions.LocalStorageNotMovedException

No way to access to my files

Everything is working on the PC or web client.
Uninstall / install does not change anything

Thks for you help

@Noni006
Copy link

Noni006 commented May 1, 2024

After lot of tests, I found the solution (in my case)
The problem came from php-fpm
With this processor, my owncloud server response as
Transfer-Encoding : chunked
so without
Content-Length

But with apache php:
serveur responce is with a
Content-Length
header
and Android client works!
A don't kown when it has changed..

@jesmrec
Copy link
Collaborator

jesmrec commented May 2, 2024

@chaotix- @geobzmm could you take a look to @Noni006's solution? ⬆️ ⬆️ . It might fit your case as well.

@chaotix-
Copy link

chaotix- commented May 2, 2024

@jesmrec Unfortunately this is not a solution for me as I am running several different virtual servers that need to run under different users. I don't think this is configurable with mod_php so I need to use php-fpm.

@JuancaG05
Copy link
Collaborator

This could be related: https://central.owncloud.org/t/download-failed-unknown-error/47935
Will research a bit about this and see if the problem is a common one for all cases 🚀

@linkp
Copy link

linkp commented May 3, 2024

That is my post over at ownCloud Central. I can confirm that the files I tested were text files (markdown, specifically).

I also have been using PHP-FPM with my ownCloud instance for many years and cannot substitute mod PHP.

@dapkdapk
Copy link

dapkdapk commented May 4, 2024

@linkp @chaotix- @geobzmm I also use only php-fpm instances and had the same problem. by adding the line SetEnv ap_trust_cgilike_cl to the .htaccess file, my problem was solved.

@iasdeoupxe
Copy link

Might worth to mention that OP is using / running:

ownCloud server version: Infinite Scale Community v4.0.3

but other users mention php-fpm bot oCIS doesn't use PHP so this could be something different or even independent from the underlying server variant (oCIS vs. ownCloud 10).

Also not even sure if using php-fpm is officially supported for the PHP variant of ownCloud.

@JohnHardline
Copy link

@linkp @chaotix- @geobzmm I also use only php-fpm instances and had the same problem. by adding the line SetEnv ap_trust_cgilike_cl to the .htaccess file, my problem was solved.

This worked for me as well

@chaotix-
Copy link

chaotix- commented May 6, 2024

It works for me as well. But I had to put it in the .htaccess file in my owncloud-data folder as it is not a subfolder of the owncloud folder.

@JuancaG05
Copy link
Collaborator

Hey @chaotix- , @JohnHardline, @iasdeoupxe, @dapkdapk, @Noni006 glad you found a solution, that seems to be server-related. Could you tell us which server version are you using? So that we can locate the error more easily and maybe solve whatever we need to solve from our side if needed

@JuancaG05
Copy link
Collaborator

@DeepDiver1975 all these problems seem to be related with an incorrect received Content-Length, are you aware of something changing in this regard recently?

@jvillafanez
Copy link
Member

Side note: php-fpm is NOT supported with OC10. You're on your own. You can use a docker environment to setup ownCloud using the official docker image in an isolated way so it doesn't disturb the rest of your installation.

As for oCIS, please try to upgrade to 5.0.3 because it might be fixed there. It could be a server-side issue.

@dapkdapk
Copy link

dapkdapk commented May 7, 2024

Hey @chaotix- , @JohnHardline, @iasdeoupxe, @dapkdapk, @Noni006 glad you found a solution, that seems to be server-related. Could you tell us which server version are you using? So that we can locate the error more easily and maybe solve whatever we need to solve from our side if needed

Hi @JuancaG05 , this is my owncloud server version and php info lines below. Hope that helps.

version: 10.14.0.3
edition: Community
PHP Version 7.4.33
System	Linux dd29232 5.4.0-174-generic #193-Ubuntu SMP Thu Mar 7 14:29:28 UTC 2024 x86_64
Build Date	Apr 15 2024 11:22:17
Server API	FPM/FastCGI

@iasdeoupxe
Copy link

IF the users running the PHP version of ownCloud are really having the same problem as the OP using the non-PHP OCIS then it is really surprising how this should be a server side issue if two completely different technologies suddenly causing the very same issue and one requires an update (OCIS) while the other requires server side modifications in the PHP configuration (OC 10).

Sounds more that something changed on the client side (be it in the app itself, in a library or in Android).

@NoSilentRunning
Copy link

Just wanted to add that since about a week's time I was facing the same problem (all filetypes affected, on multiple android phones) and adding the SetEnv to the (main) .htaccess file solved the issue.

@jesmrec
Copy link
Collaborator

jesmrec commented May 8, 2024

Just wanted to add that since about a week's time I was facing the same problem (all filetypes affected, on multiple android phones) and adding the SetEnv to the (main) .htaccess file solved the issue.

i get your point and this is also surprising for us. Last app version is two months ago, and server version the same. No changes in last week or last three weeks. Keep checking...

@jvillafanez
Copy link
Member

@iasdeoupxe the common problem is that the server isn't sending the content-length header, or it sends it with a 0 length.

For OC10, as far as I know, the issue happens only with php-fpm, which, as said, it isn't supported. PHP as apache module (I think it's apache prefork) works fine (#4352 (comment))

For oCIS, the client logs show the same issue: content-length header seems to be 0 for a 207 HTTP response. I don't know the conditions for the server to send that kind of response, but there have been changes in this regard, so it's possible that the issue is solved in recent oCIS versions.

As for the android app, it has problems if the content-length of the downloaded file doesn't match the actual content. If the code didn't change, either the problem was there the whole time but nobody hit it, or android changed something about how downloads are handled if there is a mismatch with the content-length.

@jvillafanez
Copy link
Member

In addition, I'd recommend to anyone having this issue (and posting here) to provide the environment data (check the opening post). The issue was posted for an android v13 phone, which is a relatively recent version. If everyone is having the issue with that version, we could narrow down the problem.

@appiekap653
Copy link

appiekap653 commented May 8, 2024

I have the same problem.
I can upload files and see the files.
But when trying to open them or download them I get unknown error while downloading.
Filetype does not matter.

Specs:

Android 14
Samsung OneUI 6.0
Owncloud Android app 4.2.1

Server: Ocis 5.0.3

Logs:

2024-05-08T11:32:53Z WRN http |
service=storage-system pkg=rhttp 
traceid=############### host=127.0.0.1 
method=GET uri=/data/spaces/
jsoncs3-share-manager-metadata%21jsoncs3-share
-manager-metadata/groups/
########-###--####-####-############/
received.json url=/groups/
########-####-####-####-############/
received.json proto=HTTP/1.1 status=404 size=0 
start=08/May/2024:11:32:53 +0000 end=08/May/
2024:11:32:53 +0000 time_ns=154780 
line=github.com/cs3org/reva/[email protected]/internal
/http/interceptors/log/log.go:112 

@jesmrec
Copy link
Collaborator

jesmrec commented May 8, 2024

@appiekap653 did you notice the error recently? did you update the app?

@appiekap653
Copy link

@appiekap653 did you notice the error recently? did you update the app?

I just installed owncloud for the first time yesterday.
So this is the first time I tried everything and came on this error.

@appiekap653
Copy link

appiekap653 commented May 8, 2024

I just checked if downloading the same file was working with the web-client and that worked without problems.

Maybe I must also mention that the file was uploaded with the automatic photo upload function of the android app to a folder in a space.

@jesmrec
Copy link
Collaborator

jesmrec commented May 8, 2024

did you try to download a file in test server (ocis.owncloud.works)?

@appiekap653
Copy link

Great to here you can reproduce it now.

Do you still need my server to test?
I have disabled cloudflare proxy and have removed all other Middleware and removed my firewall rules for my server for your testing purposes.
This leaves my server pretty vulnerable...

So it would be nice if you let me know if you still need it as soon as possible. So I can re-enable my security.

@jesmrec
Copy link
Collaborator

jesmrec commented May 20, 2024

@appiekap653 please reenable, Don't be unsafe. We'll keep all of you up to date. @jvillafanez can reproduce, so that we can go with his env. Thanks a lot for letting us using your instance.

@butonic
Copy link
Member

butonic commented May 21, 2024

@jvillafanez hm when I debug a GET request the httpRes Headers that are copied with

	copyHeader(w.Header(), httpRes.Header)

they already contain the Content-Length.

👀 reading up on traefik compression, Content-Length and Accept-Encoding headers. Found: traefik/traefik#7040 (comment) and that Transfer-Encoding in removed in HTTP/2.

AFAICT traefik will compress the ocis response, set a content-encoding: gzip header AND since the content length has changed removes the Content-Length header. It does not add a transfer-encoding header because http2 forbids it. Similar to cloudflare, traefix strems the content and thus has to remove the correct Content-Length when using compression.

@butonic
Copy link
Member

butonic commented May 21, 2024

@geobzmm regarding PHP in the url. We are just providing the same URLs for backwards compatability. Actually, the remote.php/ can be omitted from all URLs, but some clients or libraries still have it hardcodet.

Also, I'm a little worried about HTTP/2 and traefik dropping the Content-Lenght when enabling the compression middleware. AFAIK clients rely on the Content-Length header ... we need to investigate, but please disable compression for now to be on the safe side.

@appiekap653
Copy link

@butonic when sending the header Accept-Encoding Identity, Traefik shouldn't compress the response with gzip.
And when looking at the codebase of the Compress Middleware it doesn't indeed.

@jvillafanez
Copy link
Member

Quoting https://pkg.go.dev/net/http#ResponseWriter Write([]byte) (int, error)

	// If [ResponseWriter.WriteHeader] has not yet been called, Write calls
	// WriteHeader(http.StatusOK) before writing the data. If the Header
	// does not contain a Content-Type line, Write adds a Content-Type set
	// to the result of passing the initial 512 bytes of written data to
	// [DetectContentType]. Additionally, if the total size of all written
	// data is under a few KB and there are no Flush calls, the
	// Content-Length header is added automatically.

So golang automatically adds the content-length header for small files, but it doesn't for big files.

As seen in #4352 (comment) I don't think we're actively sending the header, so we could be relying on golang automatically sending the header (which don't work for big files) or on traefik doing some magic (which might depend on specific configuration)

@butonic
Copy link
Member

butonic commented May 21, 2024

ok, stepping through the GET code with a 7k file we indeed return no Content-Length header. @appiekap653 @jvillafanez so that is only another reason why the Content-Length header might be missing.

IMO clients cannot rely on it as the filesize as it actually only describes the length of the body, which might have been encoded in a different lenght. In propfinds owncloud introduced the oc:size property instead of the getcontentlength header for exactly this reason, IIRC.

now ... since HTTP/2 no longer mandates Content-Length ... should we still set it to the file length? even if it does not match the body length? Lets's look at the HTTP2 spec 8.1.2.6. Malformed Requests and Responses:

[...]
A request or response that includes a payload body can include a
content-length header field. A request or response is also malformed
if the value of a content-length header field does not equal the sum
of the DATA frame payload lengths that form the body
[...]

Ok, what is the 'payload length' of a DATA frame? Go read 4.1 Frame Format and 6.1 DATA. I'll wait here.

Now. AFAICT the Content-Length header, if present, has to match the sum of the length of all DATA frame payloads. Transfer encoding is forbidden in HTTP/2 ...

What about 8.4. Content-Encoding? Seeing this:

Unlike Transfer-Encoding (Section 6.1 of [HTTP/1.1]), the codings listed in Content-Encoding are a characteristic of the representation; the representation is defined in terms of the coded form, and all other metadata about the representation is about the coded form unless otherwise noted in the metadata definition. Typically, the representation is only decoded just prior to rendering or analogous usage.

And 8.6. Content-Length with

Because Content-Length is used for message delimitation in HTTP/1.1, its field value can impact how the message is parsed by downstream recipients even when the immediate connection is not using HTTP/1.1. If the message is forwarded by a downstream intermediary, a Content-Length field value that is inconsistent with the received message framing might cause a security failure due to request smuggling or response splitting.

As a result, a sender MUST NOT forward a message with a Content-Length header field value that is known to be incorrect.

We MUST NOT set Content-Length to the size of the file as it may not represent the filesize expected by the client.

This also applies to the ETAG, and we had problems when enabling compression back in the day: owncloud/core#9005

For etags we introduced X-OC-Etag.

AFAICT we need to introduce a OC-Size header (using a X- prefix is deprecated) if clients rely on this ...

AFAIU the android check tries to ensure all bytes have been received. HTTP/2 as an END_STREAM frame for that. AFAICT even if we set Content-Length to the uncompressed file length as @jvillafanez did in #4352 (comment) treafik would drop it for HTTP/2, anyway.

IMO the android app needs to learn how to handle HTTP/2 content length ... I don't see a reason to introduce a new OC-Size, yet.

@jvillafanez
Copy link
Member

Just one thing: as far as I know, the android client doesn't support HTTP2, so all the requests are HTTP1.1. Not sure about the rest of the clients.

HTTP2 might be handled by traefik at the moment. Basically, a client sends a HTTP2 request to traefik (assuming it's supported on both sides) and then traefik sends a HTTP1.1 request to oCIS (otherwise, I'm not sure how you have a HTTP2 response from traefik, but an HTTP1.1 one if it's accessed directly to oCIS)

The android client is doing an HTTP1.1 request with an accept-encoding: identity header. This means that the response should NOT be encoded / compressed.
In this case, the content-length header should match the length of the transferred data, which should also match the size of the file (because of the requested accept-encoding). If there is a mismatch, then something went wrong (the connection dies and only half of the file has been transferred, for example).
Using the content-length header is useful to show the download progress. Regardless of the content being compressed or not, knowing that you need to download 2.5GB and that you have downloaded 2MB is better than showing a spinner wheel for more than 30 minutes

It also might be a good idea for the android client to check for the content-encoding header in the response (if any) to check if the content is compressed or not even if the accept-encoding: identity has been requested just to be on the safe side because then, if a content-length header is sent, then it will mean the size of the transfer (might be compressed) and not the size of the file. I mean, it's convenient that the transfer length matches the file size, but it won't always be the case.
As mention, the android client should also handle the case where no content-length header is available, although considering the above, it should be a rare case.

As for how all of this will work with HTTP2, at least for the android client I'd say "not supported at the moment".

@felix-schwarz
Copy link

felix-schwarz commented May 21, 2024

@jesmrec @butonic The iOS client just relies on the HTTP client layer baked into the OS. That layer handles Content-Length, Transfer-Encoding and compression transparently, so the client doesn't need to worry about these. If the data arrives in chunked and/or compressed form, that layer pieces it back together and/or decompresses it before handing it to the app.

Therefore, the iOS client does not need to (and doesn't) use the value of the Content-Length header of the response at all. To verify the integrity of a file, it uses the checksum if one was provided by the server earlier. And it sends an If-Match header with the ETag of the file to ensure it gets the version it expects (or a 412 Precondition Failed response if that is no longer the current version).

On a more general note, expect that enabling compression will regularly lead to chunked responses because the transferred data is typically compressed on the fly and sent in chunks, rather than compressed as a whole before being sent.

@JuancaG05
Copy link
Collaborator

Thanks for clarifying @felix-schwarz. If you don't use Content-Length, how do you know the total size of a file then? Are you using oc:size from the PROPFIND response? And if so, when do you perform that PROPFIND?

We do need to know the total size of the file to be able to show the progress of the download (in a progress bar, for example).

@jvillafanez
Copy link
Member

Maybe, instead of a progress bar, you could just show the number of bytes written on the phone. This way, you can show progress (by increasing the number), and you don't need to know the final content length nor whether the content is compressed. Same with iOS, I expect you to write the uncompressed data (coming from the OS / library) regardless of how the transfer is done (compressed or not).

Advantages:

  • Decent UX. Progress is shown, and you can know whether a download is stuck or is being too slow.
  • No need to know the final size of the file.
  • The user should know the expected file size before downloading. The file list should show that info.

Just a little remark: this would show bytes written, not transferred.

If we can know the size of the file, we could also enhance the UX with something like 12MB / 45MB. In any case, knowing the final size is optional.

@felix-schwarz
Copy link

@JuancaG05 Yes, the file size, like the Etag that's sent with If-Match, are originating from a previous PROPFIND.

By sending the Etag for the file from the last PROPFIND as If-Match header, the app can ensure it gets either:

  • the version of the file whose metadata the app already has (=> which also means the size of the file is what the PROPFIND returned)
  • or: a 412 status response indicating the file has changed in the meantime, so a PROPFIND on the file can be sent to update the metadata for the file and a download subsequently be re-attempted

Receiving a newer/different version of the file than what the last PROPFIND returned wouldn't be good for several reasons:

  • the checksum verification (if one was provided by the server) would fail, which would make the app determine the file contents was not properly or fully received, and result in the app discarding the file it just downloaded
  • the Etag would change for the file with the next PROPFIND (f.ex. while discovering changes), from the outdated one (at the time of download) to the actual one (for the file that was already downloaded). This would result in the app discarding the file it just downloaded - because it has to assume the file is has downloaded is a different version than the file on the server, due to the Etag change.

@jesmrec
Copy link
Collaborator

jesmrec commented May 22, 2024

Thanks everyone for your inputs. So, i think we should keep trusting Content-Length. If it is missing, there are several options (all the ones all of you mentioned):

  • Showing an spinner while the download works under the hood (bad UX)
  • Showing how many bytes are being written, in order to let users know that the download is running
  • Get the total size info from a previous propfind, checking the etag as well to assure client and server are talking about the same item version
  • Keep the error and then, everyone has to check its own middleware as some users above that tweak some options (not desirable)

Moving to http2 is not an option today to fix the problem mentioned in first message, probably it'll take longer to do, but we'll put it in our minds. Also, using identity (no compression) is a non-aligned value with the other clients that uses compression, something to check in close future.

@JuancaG05
Copy link
Collaborator

Hey, I just uploaded an APK with a potential fix for this problem. Could you test it to see if it works for you? 🙂
You can find it here:

Link: https://infinite.owncloud.com/s/AXxVvNToDiqtMxd
Password: zI<6:2zW%c9J

@appiekap653
Copy link

For me that works now

@JuancaG05
Copy link
Collaborator

What about the rest? Could you take a minute to test it? 😄

Link: https://infinite.owncloud.com/s/AXxVvNToDiqtMxd
Password: zI<6:2zW%c9J

@geobzmm @chaotix- @Noni006 @linkp @dapkdapk @iasdeoupxe @JohnHardline @NoSilentRunning @peterjpierre @ whoever wants to test it? 👀

@peterjpierre
Copy link

I can confirm it is working now as well ... will there also be a corrected version for iPhone?

@jesmrec
Copy link
Collaborator

jesmrec commented May 29, 2024

I can confirm it is working now as well ... will there also be a corrected version for iPhone?

are you reproducing this in iOS as well??

@peterjpierre
Copy link

A friend of mine has an iPhone and he has the same problem not being able to download / open files

@jesmrec
Copy link
Collaborator

jesmrec commented May 29, 2024

A friend of mine has an iPhone and he has the same problem not being able to download / open files

Not sure if it'd be the same problem, because the iOS app prevents the situation we fixed (check here how it works). In any case, it'd useful to create an issue in the iOS open repo with all details as posible, so that @felix-schwarz could take a look. Here the topic should be the Android app. Thanks for testing!

@JuancaG05
Copy link
Collaborator

Well, this is already sent to Google for review and very soon it will be available in the Play Store, becoming the 4.2.2 version of the app.

Thanks to everyone who was involved here, but specially to the community for reporting, helping and collaborating with us! ❤️

Closing this ticket, but in any case, if you keep reproducing it with the new 4.2.2 version or whatever, feel free to open a new issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment