sabre-io / dav

sabre/dav is a CalDAV, CardDAV and WebDAV framework for PHP
http://sabre.io
BSD 3-Clause "New" or "Revised" License
1.51k stars 344 forks source link

HTTP GET requests on vCard items yield a version 3.0 vCard (VCF) rather than version 4.0 vCard in common Web browsers #1190

Open MetaEntropy opened 5 years ago

MetaEntropy commented 5 years ago

bug description When an HTTP GET request is performed on a vCard, a content negotiation happens, based on the Accept header of the HTTP GET request.

If the Accept header does not explicitly contain "text/vcard; version=4.0", then, sabre/dav defaults to version 3.0 vCard, downgrading high quality vCards from its database. The '/' specified in common Web browsers (Firefox, Internet Explorer, Chrome) matches the version 3.0 vCard format too.

The root of this problem is in the negotiateVCard() function in lib/CardDAV/Plugin.php / matches text/vcard without a specific version number text/vcard without specific version number is interpreted as version 3.0 vCard.

vCard 4.0 is mature and widely supported. It should be the default version.

discussion RFC 6350 defines the text/vcard MIME type.

Interoperability considerations: The text/vcard media type is intended to identify vCard data of any version. There are older specifications of vCard [RFC2426][vCard21] still in common use. While these formats are similar, they are not strictly compatible. In general, it is necessary to inspect the value of the VERSION property (see Section 6.7.9) for identifying the standard to which a given vCard object conforms.

It does not specify a default text/vcard version. When none is specified, I think that sabre/dav should either default to version 4.0 (best format) or to the internally stored format (i.e. no conversion -> no data loss).

The following patch uses the first approach (defaulting to version 4.0). It is based on the code of Baikal 0.6.0 which may not be the most up to date.

vcard-HTTP-GET-defaults-to-version-4.0.patch.txt

steps to reproduce

  1. Install Baikal 0.6.0 (it is the easiest way to see it in production)
  2. Create an addressbook and upload a sample version 4.0 vCard, with IMPP and RELATED fields.
  3. Launch a Web Browser (tested on Firefox 68), and download the vCard (VCF file).
  4. Open the file with a text editor
  5. See that the VERSION field is set to 3.0

Other solution (more powerful testing). Follow steps 1 and 2. Then, launch the command curl --basic --user XXXXX:XXXX -H 'Accept:/' http://example.com/baikal/html/card.php/addressbooks/john/default/test.vcf

See that the VERSION field is set to 3.0

related bug I first submitted this as a bug report to nextcloud https://github.com/nextcloud/server/issues/16922

evert commented 5 years ago

This is by design. Many CardDAV clients only support version 3.0, and the ones that support 4.0 tend to explicitly state this. Furthermore, clients that support 4.0 tend to also support 3.0.

Originally only 3.0 was supported. This was the only sane way to introduce vCard 4.0 support. I can imagine there might be a future where 4.0 has overwhelming support, but I don't think this is the case today. It's good to be explicit anyway.