keeweb / keeweb

Free cross-platform password manager compatible with KeePass
https://keeweb.info
Other
12.27k stars 1.09k forks source link

Webdav XMLHttpRequest cacheing causing stale Last-Modified date #344

Closed countableSet closed 8 years ago

countableSet commented 8 years ago

what were your actions? I have two computers, A and B both connected to a webdav for the .kdbx file. I added an entry to the db file on computer A and save. On computer B, I opened keeweb, and searched for the new entry added on computer A.

what was wrong? Computer B doesn't get the new modified file from webdav instead loads from cache.

app version v1.3.1

your user-agent (from Settings/Help section) User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) KeeWeb/1.3.1 Chrome/52.0.2743.82 Electron/1.3.3 Safari/537.36 and User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHMTL, like Geko) KeeWeb/1.2.4 Chrome/51.0.2704.106 Electon/1.2.6 Safari/537.36

does it happen on Demo or New database? I didn't try it with on demo or new database, but don't see way it wouldn't happen with those.

please, open dev tools in your browser and attach output log from Console tab (if you are using desktop app, devtools can be opened from Settings/General/Advanced)

[INFO ] 2016-09-05T19:38:31.637Z [open:master-db] File open request
[INFO ] 2016-09-05T19:38:31.638Z [open:master-db] Open file from storage webdav
[INFO ] 2016-09-05T19:38:31.638Z [open:master-db] Stat file
[DEBUG] 2016-09-05T19:38:31.638Z [storage-webdav] Stat http://example.com/master-db.kdbx
[DEBUG] 2016-09-05T19:38:31.639Z [storage-webdav] Stated http://example.com/master-db.kdbx Mon, 22 Aug 2016 05:17:01 GMT 1ms
[INFO ] 2016-09-05T19:38:31.640Z [open:master-db] Open file from cache because it is latest 
[DEBUG] 2016-09-05T19:38:31.640Z [storage-cache] Load 95a54799-35c7-7c62-7fac-51cd24548d16
[DEBUG] 2016-09-05T19:38:31.641Z [storage-cache] Loaded 95a54799-35c7-7c62-7fac-51cd24548d16 0ms
[INFO ] 2016-09-05T19:38:31.642Z [open:master-db] Loaded file from cache 
[INFO ] 2016-09-05T19:38:31.727Z [file] Opened file master-db: 84ms, 6000 rounds, 10 kB
[DEBUG] 2016-09-05T19:38:31.727Z [app] Add last open file 95a54799-35c7-7c62-7fac-51cd24548d16 master-db webdav http://example.com/master-db.kdbx Mon, 22 Aug 2016 05:17:01 GMT

Seems the XMLHttpRequest request for the head information is cached. screenshot-edit Therefore, the last-modified date used to determine if to load from cache isn't accurate. Cached request version is getting last-modified date of Mon, 22 Aug 2016 05:17:01 GMT Using curl gets the correct last-modified date of Mon, 05 Sep 2016 18:29:35 GMT

$ curl --user 'user:password' --head  http://example.com/master-db.kdbx
HTTP/1.1 200 OK
Date: Mon, 05 Sep 2016 19:20:45 GMT
Server: Apache
Last-Modified: Mon, 05 Sep 2016 18:29:35 GMT
ETag: "33007cf-281e-53bc6dcb14ace"
Accept-Ranges: bytes
Content-Length: 10270
Content-Type: text/plain
antelle commented 8 years ago

What happens if you add short expiration time headers for your server?

countableSet commented 8 years ago

I can check the about adding header information. Since it's running on a nas device I'm not too sure right now what configuration options I have.

But even so, it still seems like it should never use cached information to determine whether to download the file or not (ignoring whatever cache control or expiration times from the server). I could see this as potentially destructive, since if users weren't careful of this fact, they could overwrite the db file without all the latest changes.

antelle commented 8 years ago

What's your proposal, how can we make it better?

countableSet commented 8 years ago

Seems there are two prominent options, from what I could find:

1.

Appending a timestamp or 'random' number as a parameter ?rand=09809807896768 http://stackoverflow.com/questions/3984961/prevent-xmlhttpreq-s-browser-caching http://stackoverflow.com/questions/14181859/javascript-how-to-prevent-caching-in-xmlhttprequest-from-js

Surpiringly w3 references this option too

In the example above, you may get a cached result. To avoid this, add a unique ID to the URL: http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp

2.

Adding cache control to the request xhr.setRequestHeader('Cache-Control', 'no-cache'); https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4 http://webmasters.stackexchange.com/questions/30808/how-should-cache-control-be-set-in-the-requests

13.1.6 Client-controlled Behavior A client's request MAY specify the maximum age it is willing to accept of an unvalidated response; specifying a value of zero forces the cache(s) to revalidate all responses. http://www.ietf.org/rfc/rfc2616.txt

Another reference about caching https://www.mnot.net/cache_docs/

antelle commented 8 years ago

In webdav, it's not common to add timestamp, so we can go with option 2, although it may not work stable. I'll check this,