0

I'm attempting to create a new event in an iCloud calendar. I'm getting a valid-calendar-object-resource error, which according to the spec says my PUT request doesn't meet Section 4.1 in the spec.

However, this is the body of the request, which, as far as I can tell, does meet all the requirements in 4.1:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//sebbo.net//ical-generator//EN
BEGIN:VEVENT
UID:3xq8@the-calendar-api.herokuapp.com
SEQUENCE:0
DTSTAMP:20160113T023753Z
DTSTART:20160113T033753Z
DTEND:20160113T043753Z
SUMMARY:Example Event
DESCRIPTION:It works
END:VEVENT
END:VCALENDAR

Is there anything wrong with that iCalendar data, or would the error be elsewhere?

Request options

Using request for Node

{"auth":{"user":"feifan@me.com","pass":"XXX"},"headers":{"Content-Type":"text/calendar","Depth":"1","User-Agent":"DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"},"method":"PUT","url":"https://p05-caldav.icloud.com/267369040/calendars/home/","body":"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//sebbo.net//ical-generator//EN\r\nBEGIN:VEVENT\r\nUID:cc2x@the-calendar-api.herokuapp.com\r\nSEQUENCE:0\r\nDTSTAMP:20160114T061844Z\r\nDTSTART:20160114T071844Z\r\nDTEND:20160114T081844Z\r\nSUMMARY:Example Event\r\nDESCRIPTION:It works\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"}

Response:

<?xml version='1.0' encoding='UTF-8'?><error xmlns='DAV:'><valid-calendar-object-resource xmlns='urn:ietf:params:xml:ns:caldav'/></error>

CURL Attempt

curl -v -X PUT -H "Content-Type:text/calendar" -H "User-Agent:DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)" -u "feifan@me.com:XXXXX" --data-binary @- https://p05-caldav.icloud.com/267369040/calendars/home/  <<EOF
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//sebbo.net//ical-generator//EN
BEGIN:VEVENT
UID:3xq8@the-calendar-api.herokuapp.com
SEQUENCE:0
DTSTAMP:20160113T023753Z
DTSTART:20160113T033753Z
DTEND:20160113T043753Z
SUMMARY:Example Event
DESCRIPTION:It works
END:VEVENT
END:VCALENDAR
EOF

CURL verbose response

Trying 17.248.128.211...
* Connected to p05-caldav.icloud.com (17.248.128.211) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.icloud.com
* Server certificate: Apple IST CA 2 - G1
* Server certificate: GeoTrust Global CA
* Server auth using Basic with user 'feifan@me.com'
> PUT /267369040/calendars/home/ HTTP/1.1
> Host: p05-caldav.icloud.com
> Authorization: Basic XXXXXX=
> Accept: */*
> Content-Type:text/calendar
> User-Agent:DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)
> Content-Length: 273
>
* upload completely sent off: 273 out of 273 bytes
< HTTP/1.1 403 Forbidden
< Content-Type: text/xml
< DAV: 1, access-control, calendar-access, calendar-schedule, calendar-auto-schedule, calendar-managed-attachments, calendarserver-sharing, calendarserver-subscribed, calendarserver-home-sync
< Server: iCloudCalendarServer 15G33
< Date: Thu, 14 Jan 2016 15:40:18 GMT
< X-Responding-Server: st11p02me-caldav042 11 a63660a6f7d1a25b5a7ed66dab0da843
< X-Transaction-Id: b22d6d88-e7dd-4766-a92a-b42dca0775f3
< Content-Length: 137
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< Via: icloudedge:sv05p00ic-ztde010832:8401:15G126:San Jose
< X-Apple-Request-UUID: b22d6d88-e7dd-4766-a92a-b42dca0775f3
< Access-Control-Expose-Headers: X-Apple-Request-UUID
< Access-Control-Expose-Headers: Via
< x-apple-edge-info: AAAAAQA7aHR0cHM6Ly9wMDItY2FsZGF2LmljbG91ZC5jb206NDQzLzI2NzM2OTA0MC9jYWxlbmRhcnMvaG9tZS8ACXVuZGVmaW5lZAAA
<
* Connection #0 to host p05-caldav.icloud.com left intact
<?xml version='1.0' encoding='UTF-8'?><error xmlns='DAV:'><valid-calendar-object-resource xmlns='urn:ietf:params:xml:ns:caldav'/></error>
Community
  • 1
  • 1
FeifanZ
  • 16,250
  • 7
  • 45
  • 84
  • Did you add any headers beside authentication? Did you PUT the event to your personal calendar or to a shared calendar? – Marten Jan 13 '16 at 07:23
  • The full HTTP interaction (excluding pwd of course) would be interesting to see (i.e. a Charles trace). Is the iCalendar data terminated with LF (instead of just CR LF)? I'm somewhat confident that 'valid-calendar-object-resource' error is only raised if the parser fails, not in other circumstances. – hnh Jan 13 '16 at 13:02
  • Looks like iCloud accepts both, LF and CR LF. I still can upload the event successfully with both line terminations. – Marten Jan 13 '16 at 17:11
  • Does the client render any envelope, prefix or postfix? Looks like the iCloud parser is rather tolerant. Even if I insert a line like "yxcy – Marten Jan 13 '16 at 17:21
  • I'm sending the PUT to my `/home` calendar, and set the content-type header. Request details and response in updated question – FeifanZ Jan 14 '16 at 06:22
  • Can you try to upload the file using `curl` or any REST browser plugin? – Marten Jan 14 '16 at 08:53
  • Tried cURL, same result. Updated with cURL command and verbose output – FeifanZ Jan 14 '16 at 15:44
  • I've updated my answer. – Marten Jan 14 '16 at 16:51

2 Answers2

1

The iCalendar data itself seems to be fine, since it works for me. I can upload your event to my account and it appears in my calendar.

Please make sure that

  1. you specify the correct content-type text/calendar when you PUT the event.
  2. the collection that you're writing to actually supports events. iCloud uses separate collections for VEVENTs and VTODOs. Although, if I try to write to a VTODO-only collection, I get a redirect to the main calendar collection instead of an error.

update

Two more comments on your request.

  1. sending a Depth header with a PUT request doesn't make any sense and you should remove it, but it won't cause the error

  2. your PUT is directed to the calendar collection URL, not to a member URL of the collection. Most servers would just reject that right away. iCloud seem to accept that and creates the event anyway. But it looks like you can do that only once. Subsequent PUT requests to the calendar collection URL are rejected with a 412 Precondition Failed error (even if the UID is different) until the event is deleted.

    You should append a random filename. It's good practice to use something that contains the UID of the event like <UID>.ics, but you should consider to remove the @ first, since there is a lot of confusion about when or whether to encode it or not.

However, I'm still not able to reproduce the issue with this data.

update

Ok, now I'm able to reproduce it. As noted above the problem is that you don't specify a file name in your URL.

Try the curl request again like this:

curl -v -X PUT -H "Content-Type:text/calendar" -u "feifan@me.com:XXXXX" --data-binary @- https://p05-caldav.icloud.com/267369040/calendars/home/3xq8the-calendar-api.herokuapp.com.ics  <<EOF
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//sebbo.net//ical-generator//EN
BEGIN:VEVENT
UID:3xq8@the-calendar-api.herokuapp.com
SEQUENCE:0
DTSTAMP:20160113T023753Z
DTSTART:20160113T033753Z
DTEND:20160113T043753Z
SUMMARY:Example Event
DESCRIPTION:It works
END:VEVENT 
END:VCALENDAR
EOF

Note the file name at the end of the url. Also as @hnh has mentioned, use your own user agent. Don't let your client pretend to be someone else.

Community
  • 1
  • 1
Marten
  • 3,802
  • 1
  • 17
  • 26
  • Marten, if you write a VTODO to a collection which does not support them, the server must return a `supported-calendar-component` precondition. What you see looks like a hack to support older clients, but you shouldn't ever see a `valid-calendar-object-resource` in that situation. (RFC 4791 5.2.3) – hnh Jan 13 '16 at 13:06
  • Strange enough, I didn't manage to reproduce this error message. Uploading an event with a colliding UID as well as uploading complete junk return different error messages. – Marten Jan 13 '16 at 17:29
  • Complete junk may not trigger it as the parser might not kick in. Try a mostly valid iCalendar with some required property missing. You can also grep the CalendarServer source for valid-calendar-data ... – hnh Jan 13 '16 at 17:33
  • I'm setting the content type header and writing to my `/home` calendar … I've updated the question with the request and response headers I'm sending – FeifanZ Jan 14 '16 at 06:22
  • 3. Setting the User-Agent to something you are not may trigger different behaviour in the server. Don't do that, use an own UA. – hnh Jan 14 '16 at 13:28
  • Thanks Marten — adding the filename made it work! Also, will do @hnh, thanks – FeifanZ Jan 15 '16 at 16:42
  • Just noticed that removing the `Depth: 1` header causes a (likely different) 403 error. Currently don't have time to investigate, but posting this in case someone else runs into this issue. – FeifanZ Jan 19 '16 at 07:07
  • I doubt that the removal of this header on a PUT request results in a 403 error. You probably have changed something else. None of our CalDAV/CardDAV clients ever sends a Depth header in a PUT and we don't see any issues with that. – Marten Jan 19 '16 at 13:25
0

Just ran into the same error message. The fix for me was to switch to POST rather than PUT. POST is the appropriate HTTP method when you're creating a new resource, while PUT is for replacing an existing resource. Changing the method resolved the issue for me.

In the above case, the curl command would begin as follows:

curl -v -X PUT ...

Sasha Vodnik
  • 195
  • 9