CalDAV 请求 gGt iCloud 日历事件

Posted

技术标签:

【中文标题】CalDAV 请求 gGt iCloud 日历事件【英文标题】:CalDAV Request To gGt iCloud Calendar Events 【发布时间】:2016-05-08 11:40:54 【问题描述】:

我正在尝试构建一个 HTTP 请求以从 iCloud 日历中获取事件。我可以获取日历的详细信息(通过 PROPFIND)并通过其事件 id (GET) 获取单个日历事件的详细信息,但无法编写返回指定时间范围内的日历事件的请求。

谁能看到我在下面的代码中做错了什么?我得到的唯一响应是(代码 207)。在设置的时间范围内,日历中有一个事件。

<multistatus xmlns="DAV:"/>

发件人:

REPORT /<ICLOUD_USER_ID>/calendars/<ICLOUD_CALENDAR_ID>/ HTTP/1.1
Authorization: Basic <AUTHDATA>
Depth: 2
Prefer: return-minimal
Host: p31-caldav.icloud.com
Connection: close
User-Agent: Paw/2.2.2 (Macintosh; OS X/10.11.2) GCDHTTPRequest
Content-Length: 367

<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">      
    <d:prop>
        <c:calendar-data />
    </d:prop>
    <c:filter>        
        <c:comp-filter name="VCALENDAR">
            <c:comp-filter name="VEVENT">
                <c:time-range start="20160524T000000Z" end="20160526T000000Z" />
            </c:comp-filter>
        </c:comp-filter>
     </c:filter>
</c:calendar-query>

提前致谢,

杰米


编辑:有效的获取请求:

请求:

GET /<ICLOUD_USER_ID>/calendars/<ICLOUD_CALENDAR_ID>/<ICLOUD_EVENT_ID>.ics HTTP/1.1
Authorization: Basic <AUTHDATA>
Depth: 1
Prefer: return-minimal
Host: p31-caldav.icloud.com
Connection: close
User-Agent: Paw/2.2.2 (Macintosh; OS X/10.11.2) GCDHTTPRequest

回复:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//Mac OS X 10.11.2//EN
CALSCALE:GREGORIAN
BEGIN:VTIMEZONE
TZID:Australia/Sydney
X-LIC-LOCATION:Australia/Sydney
BEGIN:STANDARD
DTSTART:18950201T000000
RDATE;VALUE=DATE-TIME:18950201T000000
TZNAME:AEST
TZOFFSETFROM:+100452
TZOFFSETTO:+1000
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19170101T000100
RDATE;VALUE=DATE-TIME:19170101T000100
RDATE;VALUE=DATE-TIME:19420101T020000
RDATE;VALUE=DATE-TIME:19420927T020000
RDATE;VALUE=DATE-TIME:19431003T020000
RDATE;VALUE=DATE-TIME:19861019T020000
RDATE;VALUE=DATE-TIME:20000827T020000
TZNAME:AEDT
TZOFFSETFROM:+1000
TZOFFSETTO:+1100
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:19170325T020000
RDATE;VALUE=DATE-TIME:19170325T020000
RDATE;VALUE=DATE-TIME:19420329T020000
RDATE;VALUE=DATE-TIME:19720227T030000
RDATE;VALUE=DATE-TIME:19820404T030000
RDATE;VALUE=DATE-TIME:20060402T030000
RDATE;VALUE=DATE-TIME:20070325T030000
TZNAME:AEST
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
BEGIN:STANDARD
DTSTART:19430328T020000
RRULE:FREQ=YEARLY;UNTIL=19440325T150000Z;BYDAY=-1SU;BYMONTH=3
TZNAME:AEST
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
BEGIN:STANDARD
DTSTART:19710101T000000
RDATE;VALUE=DATE-TIME:19710101T000000
TZNAME:AEST
TZOFFSETFROM:+1000
TZOFFSETTO:+1000
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19711031T020000
RRULE:FREQ=YEARLY;UNTIL=19851026T160000Z;BYDAY=-1SU;BYMONTH=10
TZNAME:AEDT
TZOFFSETFROM:+1000
TZOFFSETTO:+1100
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:19730304T030000
RRULE:FREQ=YEARLY;UNTIL=19810228T160000Z;BYDAY=1SU;BYMONTH=3
TZNAME:AEST
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
BEGIN:STANDARD
DTSTART:19830306T030000
RRULE:FREQ=YEARLY;UNTIL=19850302T160000Z;BYDAY=1SU;BYMONTH=3
TZNAME:AEST
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
BEGIN:STANDARD
DTSTART:19860316T030000
RRULE:FREQ=YEARLY;UNTIL=19890318T160000Z;BYDAY=3SU;BYMONTH=3
TZNAME:AEST
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19871025T020000
RRULE:FREQ=YEARLY;UNTIL=19991030T160000Z;BYDAY=-1SU;BYMONTH=10
TZNAME:AEDT
TZOFFSETFROM:+1000
TZOFFSETTO:+1100
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:19900304T030000
RRULE:FREQ=YEARLY;UNTIL=19950304T160000Z;BYDAY=1SU;BYMONTH=3
TZNAME:AEST
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
BEGIN:STANDARD
DTSTART:19960331T030000
RRULE:FREQ=YEARLY;UNTIL=20050326T160000Z;BYDAY=-1SU;BYMONTH=3
TZNAME:AEST
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20011028T020000
RRULE:FREQ=YEARLY;UNTIL=20071027T160000Z;BYDAY=-1SU;BYMONTH=10
TZNAME:AEDT
TZOFFSETFROM:+1000
TZOFFSETTO:+1100
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:20080406T030000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZNAME:AEST
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20081005T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=10
TZNAME:AEDT
TZOFFSETFROM:+1000
TZOFFSETTO:+1100
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20160331T004928Z
UID:86ABADB9-CDC3-45D0-B932-5420DC10390A
DTEND;TZID=Australia/Sydney:20160425T093000
SUMMARY:Sample Event
DTSTART;TZID=Australia/Sydney:20160425T073000
DTSTAMP:20160509T000541Z
LAST-MODIFIED:20160408T220749Z
SEQUENCE:1
TRANSP:OPAQUE
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC
END:VEVENT
END:VCALENDAR

【问题讨论】:

可以添加活动的 iCalendar 吗?你确定你查询的是正确的日历吗? 肯定我在正确的日历上,因为我可以使用 GET 请求从该日历中检索单个事件;只是 REPORT 请求似乎对我不起作用 将 GET 返回的 iCalendar 添加到您的 Q 我已添加它 - 事件 ID 来自从 OS X 日历应用程序导出 ics 文件,然后读取其 ID 并将其添加到请求中 因为它看起来不寻常 - 只是为了确定,你真的在​​查询两天 - 不是一天,从 5/24 到 5/26?因为您的 4/25 事件实际上是 UTC 的 4/24 ... 【参考方案1】:

没有像Depth: 2 这样的东西。你可能想要Depth: 1

检查:RFC2518

【讨论】:

更改为深度 1,结果没有变化,但还是感谢您的发现【参考方案2】:

这是关于日历提供程序的实现。请求的主体完全没问题,看到事件 iCalendar 表示,请求的响应应该返回事件。

我看到的唯一可能导致此问题的是 Prefer: return-minimal 标头。请参阅The "return-minimal" Preference 了解更多信息。 calendar-query REPORT 只请求calendar-data。通常客户端请求eTags,因此它检查它拥有的日历对象和服务器中的日历对象之间是否有任何差异,如果有任何不同的日历对象,则客户端发送CALDAV:calendar-multiget REPORT和@987654327 @ 不同的日历对象。

尝试删除Prefer: return-minimal 标头,或者尝试更改

<d:prop>
    <c:calendar-data />
</d:prop>

<d:prop>
    <d:getetag />
</d:prop>

希望对你有帮助。

【讨论】:

return-minimal 是不太可能的原因,但仅查询 etag 是一个非常好的建议。服务器很可能只支持时间范围查询的一​​部分属性。 我知道这不太可能发生,但是使用请求calendar-data 的标头没有任何意义,因为对此的响应根本不会是最小的。这就是为什么我认为他应该删除标题并要求 calendar-data 或要求 eTags 具有相同的标题。 为 getetag 指定标头也没有意义,因为此属性“始终”存在。它对日历集合最有用,因为它们的属性不太统一。【参考方案3】:

按照建议,尝试只询问 etag,然后使用已回答的 url 获取 calendar-multiget REPORT。

我可以向您推荐使用 fiddler 或任何其他程序,以便您可以清楚地看到请求和响应。还可以尝试查看来自其他客户端(例如 emClient)的请求。

【讨论】:

【参考方案4】:
Method-: REPORT
Content type-: application/xml; charset=utf-8
Header -: Depth : 1
URL-:GET /<ICLOUD_USER_ID>/calendars/
Set credentials
Following is RequestContent-:
<C:calendar-query xmlns:D='DAV:'
                 xmlns:C='urn:ietf:params:xml:ns:caldav'>
                                     <D:prop>
                                       <D:getetag/>
                                       <C:calendar-data>
                                         <C:comp name='VCALENDAR'>
                                           <C:prop name='VERSION'/>
                                           <C:comp name='VEVENT'>
                                             <C:prop name='SUMMARY'/>
                                             <C:prop name='DESCRIPTION'/>
                                             <C:prop name='STATUS'/>
                                              <C:prop name='TRANSP'/>
                                               <C:prop name='ATTENDEE'/>
                                             <C:prop name='UID'/>
                                             <C:prop name='DTSTART'/>
                                             <C:prop name='DTEND'/>
                                             <C:prop name='DURATION'/>
                                             <C:prop name='RRULE'/>
                                             <C:prop name='RDATE'/>
                                             <C:prop name='EXRULE'/>
                                             <C:prop name='EXDATE'/>
                                             <C:prop name='RECURRENCE-ID'/>
                                           </C:comp>
                                         </C:comp>
                                       </C:calendar-data>
                                     </D:prop>
                                     <C:filter>
       <C:comp-filter name='VCALENDAR'>
         <C:comp-filter name='VEVENT'>
           <C:time-range start='20160524T000000Z'
                         end='20160526T000000Z'/>
         </C:comp-filter>
       </C:comp-filter>
     </C:filter>
                                   </C:calendar-query>

我认为问题在于使用的 URL 和方法。使用 URL 直到日历,即 /ICLOUD_USER_ID/calendars/ 和方法应该是 REPORT。

【讨论】:

以上是关于CalDAV 请求 gGt iCloud 日历事件的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Caldav 客户端为 iCloud 日历删除重复的事件条目

ICloud Caldav连接获取日历

iCloud Caldav 连接以获取日历

CALDAV 在 icloud 中添加带有注释的事件

CALDAV 在 ICLOUD 中编辑/删除多个事件

从 iCloud 获取 CalDAV 事件返回“403 Forbidden”