403 CalDAV error: valid-calendar-object-resource

2019-09-08 09:55发布

问题:

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>

回答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.



回答2:

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 ...