mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-23 00:34:23 +00:00
491af8e42c
Allow the backend to provide a value for the `getcontentlength` property as described in [RFC 2518 section 13.4][1]. The implementation treats is as optional, allthough it is a required property per RFC. Most clients do perfectly fine without it, though. Properly setting this in the backend makes the CalDAV collection listable with clients that do require it, e.g. cadaver. [1]: https://datatracker.ietf.org/doc/html/rfc2518#section-13.4
126 lines
3.1 KiB
Go
126 lines
3.1 KiB
Go
// Package caldav provides a client and server CalDAV implementation.
|
|
//
|
|
// CalDAV is defined in RFC 4791.
|
|
package caldav
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/emersion/go-ical"
|
|
"github.com/emersion/go-webdav"
|
|
"github.com/emersion/go-webdav/internal"
|
|
)
|
|
|
|
func NewCalendarHomeSet(path string) webdav.BackendSuppliedHomeSet {
|
|
return &calendarHomeSet{Href: internal.Href{Path: path}}
|
|
}
|
|
|
|
// ValidateCalendarObject checks the validity of a calendar object according to
|
|
// the contraints layed out in RFC 4791 section 4.1 and returns the only event
|
|
// type and UID occuring in this calendar, or an error if the calendar could
|
|
// not be validated.
|
|
func ValidateCalendarObject(cal *ical.Calendar) (eventType string, uid string, err error) {
|
|
// Calendar object resources contained in calendar collections
|
|
// MUST NOT specify the iCalendar METHOD property.
|
|
if prop := cal.Props.Get(ical.PropMethod); prop != nil {
|
|
return "", "", fmt.Errorf("calendar resource must not specify METHOD property")
|
|
}
|
|
|
|
for _, comp := range cal.Children {
|
|
// Calendar object resources contained in calendar collections
|
|
// MUST NOT contain more than one type of calendar component
|
|
// (e.g., VEVENT, VTODO, VJOURNAL, VFREEBUSY, etc.) with the
|
|
// exception of VTIMEZONE components, which MUST be specified
|
|
// for each unique TZID parameter value specified in the
|
|
// iCalendar object.
|
|
if comp.Name != ical.CompTimezone {
|
|
if eventType == "" {
|
|
eventType = comp.Name
|
|
}
|
|
if eventType != comp.Name {
|
|
return "", "", fmt.Errorf("conflicting event types in calendar: %s, %s", eventType, comp.Name)
|
|
}
|
|
// TODO check VTIMEZONE for each TZID?
|
|
}
|
|
|
|
// Calendar components in a calendar collection that have
|
|
// different UID property values MUST be stored in separate
|
|
// calendar object resources.
|
|
compUID, err := comp.Props.Text(ical.PropUID)
|
|
if err != nil {
|
|
return "", "", fmt.Errorf("error checking component UID: %v", err)
|
|
}
|
|
if uid == "" {
|
|
uid = compUID
|
|
}
|
|
if uid != compUID {
|
|
return "", "", fmt.Errorf("conflicting UID values in calendar: %s, %s", uid, compUID)
|
|
}
|
|
}
|
|
return eventType, uid, nil
|
|
}
|
|
|
|
type Calendar struct {
|
|
Path string
|
|
Name string
|
|
Description string
|
|
MaxResourceSize int64
|
|
SupportedComponentSet []string
|
|
}
|
|
|
|
type CalendarCompRequest struct {
|
|
Name string
|
|
|
|
AllProps bool
|
|
Props []string
|
|
|
|
AllComps bool
|
|
Comps []CalendarCompRequest
|
|
}
|
|
|
|
type CompFilter struct {
|
|
Name string
|
|
IsNotDefined bool
|
|
Start, End time.Time
|
|
Props []PropFilter
|
|
Comps []CompFilter
|
|
}
|
|
|
|
type ParamFilter struct {
|
|
Name string
|
|
IsNotDefined bool
|
|
TextMatch *TextMatch
|
|
}
|
|
|
|
type PropFilter struct {
|
|
Name string
|
|
IsNotDefined bool
|
|
Start, End time.Time
|
|
TextMatch *TextMatch
|
|
ParamFilter []ParamFilter
|
|
}
|
|
|
|
type TextMatch struct {
|
|
Text string
|
|
NegateCondition bool
|
|
}
|
|
|
|
type CalendarQuery struct {
|
|
CompRequest CalendarCompRequest
|
|
CompFilter CompFilter
|
|
}
|
|
|
|
type CalendarMultiGet struct {
|
|
Paths []string
|
|
CompRequest CalendarCompRequest
|
|
}
|
|
|
|
type CalendarObject struct {
|
|
Path string
|
|
ModTime time.Time
|
|
ContentLength int64
|
|
ETag string
|
|
Data *ical.Calendar
|
|
}
|