Details
Description
CBL 3.0.0+ is mishandling blobs on pull from Sync Gateway. It is trying to fetch attachments from blobs in the document, even if Sync Gateway sent no attachment metadata with the document revision.
CBL should always be acting on the contents of `_attachments` when replicating with Sync Gateway, and never inline blobs, as per: https://github.com/couchbase/couchbase-lite-core/wiki/Legacy-Attachment-Handling#pulling-from-sync-gateway
This may differ for CBL P2P, where both peers understand blobs.
Attachment vs. Blob background:
- Sync Gateway does not support blobs! Only top-level `_attachments`. CBL performs the necessary incantations to translate document blobs into these attachments during replication in both directions.
- From Sync Gateway's point of view, `_attachments` is the source of truth for what attachments exist on a document.
- If nothing is in `_attachments`, there are no attachments {}{}and will actively delete attachment data{}{} when an attachment digest is dereferenced in this way.
Setup (any CBL version):
1. Empty Bucket
2. Create SG database
-
$ curl -X PUT [http://Administrator:password@localhost:4985/db1/] -H 'Content-Type: application/json' -d ' \{"bucket":"b1","num_index_replicas":0}'
3. Create user
-
$ curl -X PUT [http://Administrator:password@localhost:4985/db1/_user/demo] -H 'Content-Type: application/json' -d ' \{"password":"password","admin_channels":["*"]}'
4. Create document with blob in CBL
-
mutableDoc.setBlob("myblob", new Blob("text/plain", "hello world".getBytes()));
- (in example/logs Doc ID `2f8a18a0-3780-4616-8320-77e6002e9b48` Rev ID `1-1abd4365f119b400300e3405a24f058f7795c62f`)
5. Push to SG
6. Remove attachment in SG -
$ curl -X DELETE http://Administrator:password@localhost:4985/db1/2f8a18a0-3780-4616-8320-77e6002e9b48/blob_%2Fmyblob?rev=1-1abd4365f119b400300e3405a24f058f7795c62f
7. See doc now with no attachments via SG:
-
$ curl http://Administrator:password@localhost:4985/db1/2f8a18a0-3780-4616-8320-77e6002e9b48
- Since SG doesn't know what blobs are, and doesn't care that "myblob" remains in the document body... The `_attachments` property and internal metadata for attachments are now empty
{"_attachments":{},"_id":"2f8a18a0-3780-4616-8320-77e6002e9b48","_rev":"2-0756c1f8f4aaaa7ab03a4f38ba0f9605","channels":["foobar"],"created_at":1694182532802,"myblob":\{"@type":"blob","content_type":"text/plain","digest":"sha1-Kq5sNclPz7QV2+lfQIuc6R7oRu0=","length":11}}
Repro/Regression description:
Need new empty CBL database to pull this document into (the bug requires the client to be pulling the new revision but also whilst it doesn't have the blob)
- CBL 2.8.6 identifies that the doc no longer has an attachment and doesn't try to pull it.
- CBL 3.0.0 thinks because it sees a blob, the doc must have an attachment, and tries to pull a non-existent attachment, which fails.
Repro Steps:
1. Create a new CBL database
2. Start a pull replication
Expected (2.8.6):
- Doc pulled without error (and no attachment/blob fetch attempted)
Actual (in 3.0.0+)
- Doc pulled but not stored - got 403 error trying to pull a non-existent attachment
2023-09-08 15:28:07.611 15117-15154 CouchbaseLite/NETWORK me.bbrks.dev.cbl.pushreplicator V \{N8litecore4blip10ConnectionE#36}
Finished receiving ERR #6
2023-09-08 15:28:07.611 15117-15154 CouchbaseLite/NETWORK me.bbrks.dev.cbl.pushreplicator I RECEIVED: ERR #6
{ Error-Domain: HTTP Error-Code: 403 BODY: Attachment's doc not being synced }
2023-09-08 15:28:07.612 15117-15154 CouchbaseL...REPLICATOR me.bbrks.dev.cbl.pushreplicator E
{N8litecore4repl11IncomingRevE#49} Got error response: HTTP 403 'Attachment's doc not being synced'
2023-09-08 15:28:07.612 15117-15154 CouchbaseL...REPLICATOR me.bbrks.dev.cbl.pushreplicator W \{N8litecore4repl11IncomingRevE#49}
failed with error: WebSocket error 403, "Attachment's doc not being synced"
- Another potential bug, the client appears to checkpoint past the failed document?