From 842acb3647f817374ef3325ae3b8e99282a42f41 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 12 Feb 2020 19:47:16 +0100 Subject: [PATCH] carddav: add Client.PutAddressObject --- carddav/client.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ carddav/server.go | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/carddav/client.go b/carddav/client.go index 9992754..0e332f1 100644 --- a/carddav/client.go +++ b/carddav/client.go @@ -3,9 +3,11 @@ package carddav import ( "bytes" "fmt" + "io" "net" "net/http" "net/url" + "strconv" "strings" "time" @@ -317,3 +319,51 @@ func (c *Client) MultiGetAddressBook(path string, multiGet *AddressBookMultiGet) return decodeAddressList(ms) } + +func (c *Client) PutAddressObject(path string, card vcard.Card) (*AddressObject, error) { + // TODO: add support for If-None-Match and If-Match + + pr, pw := io.Pipe() + + go func() { + err := vcard.NewEncoder(pw).Encode(card) + pw.CloseWithError(err) + }() + + req, err := c.ic.NewRequest(http.MethodPut, path, pr) + if err != nil { + pr.Close() + return nil, err + } + req.Header.Set("Content-Type", vcard.MIMEType) + + resp, err := c.ic.Do(req) + if err != nil { + return nil, err + } + + ao := &AddressObject{Path: path} + if loc := resp.Header.Get("Location"); loc != "" { + u, err := url.Parse(loc) + if err != nil { + return nil, err + } + ao.Path = u.Path + } + if etag := resp.Header.Get("ETag"); etag != "" { + etag, err := strconv.Unquote(etag) + if err != nil { + return nil, err + } + ao.ETag = etag + } + if lastModified := resp.Header.Get("Last-Modified"); lastModified != "" { + t, err := http.ParseTime(lastModified) + if err != nil { + return nil, err + } + ao.ModTime = t + } + + return ao, nil +} diff --git a/carddav/server.go b/carddav/server.go index 28d14f8..07b525b 100644 --- a/carddav/server.go +++ b/carddav/server.go @@ -386,7 +386,7 @@ func (b *backend) Proppatch(r *http.Request, update *internal.Propertyupdate) (* } func (b *backend) Put(r *http.Request) (*internal.Href, error) { - // TODO: add support for If-None-Match + // TODO: add support for If-None-Match and If-Match t, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) if err != nil {