diff --git a/carddav/server.go b/carddav/server.go index e4bfaaa..572ebcb 100644 --- a/carddav/server.go +++ b/carddav/server.go @@ -261,6 +261,10 @@ func (b *backend) propfindAddressObject(propfind *internal.Propfind, ao *Address return internal.NewPropfindResponse(ao.Href, propfind, props) } +func (b *backend) Proppatch(r *http.Request, update *internal.Propertyupdate) (*internal.Response, error) { + panic("TODO") +} + func (b *backend) Put(r *http.Request) error { panic("TODO") } diff --git a/internal/elements.go b/internal/elements.go index 9256e1a..5f0b90c 100644 --- a/internal/elements.go +++ b/internal/elements.go @@ -335,3 +335,22 @@ type CurrentUserPrincipal struct { Href string `xml:"href,omitempty"` Unauthenticated *struct{} `xml:"unauthenticated,omitempty"` } + +// https://tools.ietf.org/html/rfc4918#section-14.19 +type Propertyupdate struct { + XMLName xml.Name `xml:"DAV: propertyupdate"` + Remove []Remove `xml:"remove"` + Set []Set `xml:"set"` +} + +// https://tools.ietf.org/html/rfc4918#section-14.23 +type Remove struct { + XMLName xml.Name `xml:"DAV: remove"` + Prop Prop `xml:"prop"` +} + +// https://tools.ietf.org/html/rfc4918#section-14.26 +type Set struct { + XMLName xml.Name `xml:"DAV: set"` + Prop Prop `xml:"prop"` +} diff --git a/internal/server.go b/internal/server.go index 04d25d9..7c48a63 100644 --- a/internal/server.go +++ b/internal/server.go @@ -77,6 +77,7 @@ type Backend interface { Options(r *http.Request) ([]string, error) HeadGet(w http.ResponseWriter, r *http.Request) error Propfind(r *http.Request, pf *Propfind, depth Depth) (*Multistatus, error) + Proppatch(r *http.Request, pu *Propertyupdate) (*Response, error) Put(r *http.Request) error Delete(r *http.Request) error Mkcol(r *http.Request) error @@ -112,6 +113,8 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } case "PROPFIND": err = h.handlePropfind(w, r) + case "PROPPATCH": + err = h.handleProppatch(w, r) case "MKCOL": err = h.Backend.Mkcol(r) if err == nil { @@ -236,3 +239,18 @@ func NewPropfindResponse(href string, propfind *Propfind, props map[xml.Name]Pro return resp, nil } + +func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request) error { + var update Propertyupdate + if err := DecodeXMLRequest(r, &update); err != nil { + return err + } + + resp, err := h.Backend.Proppatch(r, &update) + if err != nil { + return err + } + + ms := NewMultistatus(*resp) + return ServeMultistatus(w, ms) +} diff --git a/server.go b/server.go index 39778f0..afb5753 100644 --- a/server.go +++ b/server.go @@ -185,6 +185,11 @@ func (b *backend) propfindFile(propfind *internal.Propfind, fi *FileInfo) (*inte return internal.NewPropfindResponse(fi.Href, propfind, props) } +func (b *backend) Proppatch(r *http.Request, update *internal.Propertyupdate) (*internal.Response, error) { + // TODO: return a failed Response instead + return nil, internal.HTTPErrorf(http.StatusForbidden, "webdav: PROPPATCH is unsupported") +} + func (b *backend) Put(r *http.Request) error { wc, err := b.FileSystem.Create(r.URL.Path) if err != nil {