nextcloud/tasks

Wrong server ETag stored in task after the first change

Enrico204 opened this issue · 4 comments

Steps to reproduce

  1. Create a new task
  2. Edit the new task
  3. Edit again the new task

Expected behaviour

All changes successfully saved - no conflicts.

Actual behaviour

The 2nd change results in a "conflict" (HTTP 412 Precondition Failed). Refreshing task (yellow button) results in a loss of data for the last change.

Server configuration

Operating system: Debian 11 (host) running nextcloud:22.2.10-apache docker image

Web server: nextcloud:22.2.10-apache embeds Apache 2.4.53

Database: MariaDB 10.5

PHP version: PHP 8.0.20

Nextcloud version: 22.2.10

Tasks version: 0.14.4

Updated from an older Nextcloud or fresh install: Upgraded

Signing status:

No errors have been found.

List of activated apps:

Accessibility 1.8.0
Activity 2.15.0
Brute-force settings 2.4.0
Calendar 3.4.2
Contacts 4.2.0
Contacts Interaction 1.3.0
Dashboard 7.2.0
Deleted files 1.12.0
External storage support 1.13.1
News 18.1.1
Notes 4.5.0
Notifications 2.10.1
PDF viewer 2.3.1
Photos 1.4.0
Privacy 1.6.0
Right click 1.1.0
Tasks 0.14.4
Text 3.3.1
Theming 1.13.0
Versions 1.15.0
Video player 

Nextcloud configuration:

$CONFIG = array (
  'htaccess.RewriteBase' => '/',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'apps_paths' =>
  array (
    0 =>
    array (
      'path' => '/var/www/html/apps',
      'url' => '/apps',
      'writable' => false,
    ),
    1 =>
    array (
      'path' => '/var/www/html/custom_apps',
      'url' => '/custom_apps',
      'writable' => true,
    ),
  ),
  'instanceid' => '[redacted]',
  'passwordsalt' => '[redacted]',
  'secret' => '[redacted]',
  'trusted_domains' =>
  array (
          0 => '[redacted]',
  ),
  'trusted_proxies' =>
  array (
    0 => '[redacted]',
  ),
  'datadirectory' => '/var/www/html/data',
  'dbtype' => 'mysql',
  'version' => '22.2.9.1',
  'overwrite.cli.url' => 'https://[redacted]',
  'overwriteprotocol' => 'https',
  'dbname' => 'nextcloud',
  'dbhost' => '[redacted]',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => '[redacted]',
  'dbpassword' => '[redacted]',
  'installed' => true,
  'maintenance' => false,
  'loglevel' => 2,
  'log_type' => 'file',
  'logfile' => '/tmp/nextcloud.log',
  'log_rotate_size' => '104857600',
  'config_is_read_only' => false,
  'mail_smtpname' => '[redacted]',
  'mail_smtppassword' => '[redacted]',
  'mail_smtpmode' => 'smtp',
  'mail_smtpsecure' => 'tls',
  'mail_smtpauthtype' => 'PLAIN',
  'mail_smtpauth' => 1,
  'mail_sendmailmode' => 'smtp',
  'mail_smtphost' => '[redacted]',
  'mail_smtpport' => '587',
  'mail_from_address' => '[redacted]',
  'mail_domain' => '[redacted]',
  'theme' => '',
  'default_phone_region' => 'IT',
);

Are you using external storage, if yes which one: local

Are you using encryption: no

Are you using an external user-backend, if yes which one: no

Client configuration

Browser: Firefox 100

Operating system: Debian 11

CalDAV-clients: n/a

Logs

Web server error log

192.0.2.1 - - [16/Aug/2022:09:55:13 +0000] "PUT /remote.php/dav/calendars/[redacted]/68C1E0CF-6B37-43C9-9638-AEFEBFE4FA9F/9843CBB6-1430-4FE6-9790-04AA2C9B407C.ics HTTP/1.1" 412 918 "https://[redacted]/apps/tasks/" "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0"

Nextcloud log (data/nextcloud.log)

(empty)

Browser log

First change (after the task is created):

PUT https://[redacted]/remote.php/dav/calendars/[redacted]/68C1E0CF-6B37-43C9-9638-AEFEBFE4FA9F/9843CBB6-1430-4FE6-9790-04AA2C9B407C.ics
Status: 204 No Content
Version: HTTP/2
Transferred: 2.13 KB (0 B size)
Referrer Policy: same-origin

Response headers:	
    cache-control
    	no-store, no-cache, must-revalidate
    content-security-policy
    	default-src 'none';
    date
    	Tue, 16 Aug 2022 09:55:09 GMT
    etag
    	"04fd46c7390975a2bdf9dc5dc8a13993"
    expires
    	Thu, 19 Nov 1981 08:52:00 GMT
    oc-etag
    	"04fd46c7390975a2bdf9dc5dc8a13993"
    pragma
    	no-cache
    referrer-policy
    	same-origin
    server
    	Apache/2.4.53 (Debian)
    strict-transport-security
    	max-age=31536000; includeSubDomains; preload
    x-content-type-options
    	nosniff
    x-download-options
    	noopen
    X-Firefox-Spdy
    	h2
    x-frame-options
    	SAMEORIGIN
    x-permitted-cross-domain-policies
    	none
    x-powered-by
    	PHP/8.0.20
    x-robots-tag
    	none
    x-xss-protection
    	1; mode=block

Request headers:
    Accept
    	*/*
    Accept-Encoding
    	gzip, deflate, br
    Accept-Language
    	en-US,en;q=0.5
    Connection
    	keep-alive
    Content-Length
    	239
    Content-Type
    	text/calendar; charset=utf-8; component=vtodo; charset=utf-8
    Cookie
    	[redacted]
    Depth
    	0
    DNT
    	1
    Host
    	[redacted]
    If-Match
    	"33573da910f7c617daca39591af20cc4"
    Origin
    	https://[redacted]
    Referer
    	https://[redacted]/apps/tasks/
    requesttoken
    	[redacted]
    Sec-Fetch-Dest
    	empty
    Sec-Fetch-Mode
    	cors
    Sec-Fetch-Site
    	same-origin
    Sec-GPC
    	1
    TE
    	trailers
    User-Agent
    	Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0
    X-Requested-With
    	XMLHttpRequest

"Conflict" request:

PUT https://[redacted]/remote.php/dav/calendars/[redacted]/68C1E0CF-6B37-43C9-9638-AEFEBFE4FA9F/9843CBB6-1430-4FE6-9790-04AA2C9B407C.ics
Status: 412 Precondition Failed
Version: HTTP/2
Transferred: 0.99 KB (308 B size)
Referrer Policy: same-origin

Response headers:
    cache-control
    	no-store, no-cache, must-revalidate
    content-length
    	308
    content-security-policy
    	default-src 'none';
    content-type
    	application/xml; charset=utf-8
    date
    	Tue, 16 Aug 2022 09:55:13 GMT
    etag
    	"04fd46c7390975a2bdf9dc5dc8a13993"
    expires
    	Thu, 19 Nov 1981 08:52:00 GMT
    pragma
    	no-cache
    referrer-policy
    	same-origin
    server
    	Apache/2.4.53 (Debian)
    strict-transport-security
    	max-age=31536000; includeSubDomains; preload
    x-content-type-options
    	nosniff
    x-download-options
    	noopen
    X-Firefox-Spdy
    	h2
    x-frame-options
    	SAMEORIGIN
    x-permitted-cross-domain-policies
    	none
    x-powered-by
    	PHP/8.0.20
    x-robots-tag
    	none
    x-xss-protection
    	1; mode=block

Request headers:
    Accept
    	*/*
    Accept-Encoding
    	gzip, deflate, br
    Accept-Language
    	en-US,en;q=0.5
    Connection
    	keep-alive
    Content-Length
    	264
    Content-Type
    	text/calendar; charset=utf-8; component=vtodo; charset=utf-8
    Cookie
    	[redacted]
    Depth
    	0
    DNT
    	1
    Host
    	[redacted]
    If-Match
    	0.09792412366674308
    Origin
    	https://[redacted]
    Referer
    	https://[redacted]/apps/tasks/
    requesttoken
    	[redacted]
    Sec-Fetch-Dest
    	empty
    Sec-Fetch-Mode
    	cors
    Sec-Fetch-Site
    	same-origin
    Sec-GPC
    	1
    TE
    	trailers
    User-Agent
    	Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0
    X-Requested-With
    	XMLHttpRequest

The response content for the "Conflict request is:

<?xml version="1.0" encoding="utf-8"?>
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  <s:exception>Sabre\DAV\Exception\PreconditionFailed</s:exception>
  <s:message>An If-Match header was specified, but none of the specified ETags matched.</s:message>
  <s:header>If-Match</s:header>
</d:error>

Other infos

I looked for past issues, and I found many issues with ETags (see #167), so I looked closely for config issues, and there are none. The ETag is correctly returned by the server (as you can see above), however for some reason the client loses the value and replace it with an apparently random floating point number (0.09792412366674308 in this example, as you can see in If-Match request header in the "Conflict" request).

Using the Firefox dev toolbar I looked inside OCA.Tasks.App.$store.state.tasks.tasks["9fe4c0d2-f9ea-4fcf-a7c3-f01ac2ff8b27~68C1E0CF-6B37-43C9-9638-AEFEBFE4FA9F"].dav.etag and I found that this variable is holding the correct ETag once the issue has been created (or after a page refresh or after a "re-sync" using the yellow button for resync). However, after the first change, the value is changed to this strange floating point. Then, after the failed PUT, also the .conflict property is changed to that value`.

I wasn't able to dig more for now :-(

That is really weird. I cannot explain where this number as etag comes from either. The Etag is actually handled in a separate library https://github.com/nextcloud/cdav-library, but I don't see where it could accidentally become a number there. I am still not completely convinced it isn't a config issue to be honest, especially since it works just fine on other instances. Could you please also check with other browsers, and maybe in incognito with all plugins disabled?

That is really weird. I cannot explain where this number as etag comes from either. The Etag is actually handled in a separate library https://github.com/nextcloud/cdav-library, but I don't see where it could accidentally become a number there. I am still not completely convinced it isn't a config issue to be honest, especially since it works just fine on other instances. Could you please also check with other browsers, and maybe in incognito with all plugins disabled?

Actually, you were right about browser plugins, I didn't test it and I found the problem: it's not a server side configuration, but "CleanURLs" Firefox plugins that removes ETags on purposes. Sorry, I didn't know that, it wasn't removing ETags in the past :-(

Given the popularity of the library (it's also "Recommended" by Mozilla), may I suggest to add a line in the README about the incompatibility?
(unfortunately there is no way for adding an exception for a website, the only option is to disable ETag removal)

Given the popularity of the library (it's also "Recommended" by Mozilla), may I suggest to add a line in the README about the incompatibility? (unfortunately there is no way for adding an exception for a website, the only option is to disable ETag removal)

Maybe not strictly necessary, since CleanURLs write
Release notes for 1.25.0

  • ETag filtering is now disabled by default

But feel free to send a PR to Tasks if you think it helps.

* ETag filtering is now disabled by default

This is true only for those who installs ClearURLs version 1.25.0. For those (like me) who upgrade it, the option will remain enabled (even if I never opened the preference panel in the past).

I'll create a PR :-)