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

Mobile: Simplify Dropbox sync workarond #10415

Conversation

personalizedrefrigerator
Copy link
Collaborator

@personalizedrefrigerator personalizedrefrigerator commented May 8, 2024

Summary

This pull request adjusts the Dropbox sync workaround to prevent fetch from using the cache using If-None-Match. This is similar to a workaround for WebDAV sync on iOS:

// On iOS, the network lib appends a If-None-Match header to PROPFIND calls, which is kind of correct because
// the call is idempotent and thus could be cached. According to RFC-7232 though only GET and HEAD should have
// this header for caching purposes. It makes no mention of PROPFIND.
// So possibly because of this, Seafile (and maybe other WebDAV implementations) responds with a "412 Precondition Failed"
// error when this header is present for PROPFIND call on existing resources. This is also kind of correct because there is a resource
// with this eTag and since this is neither a GET nor HEAD call, it is supposed to respond with 412 if the resource is present.
// The "solution", an ugly one, is to send a purposely invalid string as eTag, which will bypass the If-None-Match check - Seafile
// finds out that no resource has this ID and simply sends the requested data.
// Also add a random value to make sure the eTag is unique for each call.
if (['GET', 'HEAD'].indexOf(method) < 0) headers['If-None-Match'] = `JoplinIgnore-${Math.floor(Math.random() * 100000)}`;
if (!headers['User-Agent']) headers['User-Agent'] = 'Joplin/1.0';
const fetchOptions = {};
fetchOptions.headers = headers;
fetchOptions.method = method;
if (options.path) fetchOptions.path = options.path;

This is based on a suggestion from @laurent22.

Notes

  • Based on the description on MDN docs, this should prevent the cache from being used, which, based on network logs from XCode, is related to the network error.
  • The alternatives of setting cache to no-store and/or the Cache-Control header don't seem to help.
  • See this post on the Dropbox forum for additional details.

Testing

This has been tested by:

  1. Starting with an existing Dropbox sync target.
  2. From a desktop client, just over hundred notes.
  3. Adding a new note on the mobile client.
  4. Syncing the mobile client.
  5. Verifying that no errors are logged while syncing the mobile client.

This has been tested successfully on an iOS 17.4 device.

To-do:

  • Re-run the synchronizer tests with Dropbox.

@laurent22 laurent22 merged commit 3312bd2 into laurent22:release-2.14 May 12, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants