403 CalDAV error: valid-calendar-object-resource

403 CalDAV error: valid-calendar-object-resource

我正在尝试在 iCloud 日历中创建新活动。我收到 valid-calendar-object-resource 错误,根据 spec says my PUT request doesn't meet Section 4.1 in the spec.

然而,这是请求的正文,据我所知,它确实满足 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

那个 iCalendar 数据有什么问题吗,还是其他地方有错误?

请求选项

对节点使用request

{"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"}

回复:

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

CURL 尝试

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 详细响应

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>

iCalendar 数据本身似乎很好,因为它适用于我。我可以将您的活动上传到我的帐户,它会显示在我的日历中。

请确保

  1. 当您 PUT 事件时,您指定了正确的 content-type text/calendar
  2. 您正在写入的 collection 实际上支持事件。 iCloud 对 VEVENTVTODO 使用单独的 collection。虽然,如果我尝试写入 VTODO-only collection,我会重定向到主日历 collection 而不是错误。

更新

关于您的请求的另外两条评论。

  1. 发送 Depth header 和 PUT 请求没有任何意义,你应该删除它,但它不会导致错误

  2. 您的 PUT 指向日历 collection URL,而不是 collection 的成员 URL。大多数服务器会立即拒绝。 iCloud 似乎接受了这一点并创建了事件。但看起来你只能这样做一次。对日历 collection URL 的后续 PUT 请求被拒绝并出现 412 Precondition Failed 错误(即使 UID 不同),直到事件被删除。

    您应该附加一个随机文件名。最好使用包含事件的 UID 的内容,例如 <UID>.ics,但您应该首先考虑删除 @,因为对于何时或是否删除存在很多混淆编码与否。

但是,我仍然无法使用此数据重现该问题。

更新

好的,现在我可以重现它了。如上所述,问题是您没有在 URL.

中指定文件名

像这样再次尝试 curl 请求:

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

注意url末尾的文件名。另外正如@hnh 所提到的,使用您自己的用户代理。不要让你的客户假装成别人。

只是运行进入同样的错误信息。我的解决方法是切换到 POST 而不是 PUTPOST 是创建新资源时合适的 HTTP 方法,而 PUT 用于替换现有资源。更改方法为我解决了问题。

在上述情况下,curl 命令将以如下方式开始:

curl -v -X PUT ...