From 25678476dbf2073a26ea16adc05f28aee811c66d Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 3 Feb 2020 21:48:31 +0100 Subject: [PATCH] internal: add ETag --- caldav/client.go | 7 +------ carddav/client.go | 7 +------ carddav/server.go | 2 +- client.go | 7 +------ internal/elements.go | 21 ++++++++++++++++++++- server.go | 5 ++--- 6 files changed, 26 insertions(+), 23 deletions(-) diff --git a/caldav/client.go b/caldav/client.go index f7606a8..f433b65 100644 --- a/caldav/client.go +++ b/caldav/client.go @@ -3,7 +3,6 @@ package caldav import ( "fmt" "net/http" - "strconv" "time" "github.com/emersion/go-webdav" @@ -164,15 +163,11 @@ func decodeCalendarObjectList(ms *internal.Multistatus) ([]CalendarObject, error if err := resp.DecodeProp(&getETag); err != nil && !internal.IsNotFound(err) { return nil, err } - etag, err := strconv.Unquote(getETag.ETag) - if err != nil { - return nil, fmt.Errorf("carddav: failed to unquote ETag: %v", err) - } addrs = append(addrs, CalendarObject{ Path: path, ModTime: time.Time(getLastMod.LastModified), - ETag: etag, + ETag: string(getETag.ETag), Data: calData.Data, }) } diff --git a/carddav/client.go b/carddav/client.go index e89511f..b939760 100644 --- a/carddav/client.go +++ b/carddav/client.go @@ -6,7 +6,6 @@ import ( "net" "net/http" "net/url" - "strconv" "strings" "time" @@ -222,10 +221,6 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) { if err := resp.DecodeProp(&getETag); err != nil && !internal.IsNotFound(err) { return nil, err } - etag, err := strconv.Unquote(getETag.ETag) - if err != nil { - return nil, fmt.Errorf("carddav: failed to unquote ETag: %v", err) - } r := bytes.NewReader(addrData.Data) card, err := vcard.NewDecoder(r).Decode() @@ -236,7 +231,7 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) { addrs = append(addrs, AddressObject{ Path: path, ModTime: time.Time(getLastMod.LastModified), - ETag: etag, + ETag: string(getETag.ETag), Card: card, }) } diff --git a/carddav/server.go b/carddav/server.go index 494719c..28d14f8 100644 --- a/carddav/server.go +++ b/carddav/server.go @@ -372,7 +372,7 @@ func (b *backend) propfindAddressObject(propfind *internal.Propfind, ao *Address if ao.ETag != "" { props[internal.GetETagName] = func(*internal.RawXMLValue) (interface{}, error) { - return &internal.GetETag{ETag: fmt.Sprintf("%q", ao.ETag)}, nil + return &internal.GetETag{ETag: internal.ETag(ao.ETag)}, nil } } diff --git a/client.go b/client.go index da08656..02dbccf 100644 --- a/client.go +++ b/client.go @@ -4,7 +4,6 @@ import ( "fmt" "io" "net/http" - "strconv" "time" "github.com/emersion/go-webdav/internal" @@ -88,15 +87,11 @@ func fileInfoFromResponse(resp *internal.Response) (*FileInfo, error) { if err := resp.DecodeProp(&getETag); err != nil && !internal.IsNotFound(err) { return nil, err } - etag, err := strconv.Unquote(getETag.ETag) - if err != nil { - return nil, fmt.Errorf("webdav: failed to unquote ETag: %v", err) - } fi.Size = getLen.Length fi.ModTime = time.Time(getMod.LastModified) fi.MIMEType = getType.Type - fi.ETag = etag + fi.ETag = string(getETag.ETag) } return fi, nil diff --git a/internal/elements.go b/internal/elements.go index accb6de..324deae 100644 --- a/internal/elements.go +++ b/internal/elements.go @@ -342,7 +342,26 @@ type GetLastModified struct { // https://tools.ietf.org/html/rfc4918#section-15.6 type GetETag struct { XMLName xml.Name `xml:"DAV: getetag"` - ETag string `xml:",chardata"` + ETag ETag `xml:",chardata"` +} + +type ETag string + +func (etag *ETag) UnmarshalText(b []byte) error { + s, err := strconv.Unquote(string(b)) + if err != nil { + return fmt.Errorf("webdav: failed to unquote ETag: %v", err) + } + *etag = ETag(s) + return nil +} + +func (etag *ETag) MarshalText() ([]byte, error) { + return []byte(fmt.Sprintf("%q", *etag)), nil +} + +func (etag ETag) String() string { + return string(etag) } // https://tools.ietf.org/html/rfc4918#section-14.5 diff --git a/server.go b/server.go index f1a326f..811ef10 100644 --- a/server.go +++ b/server.go @@ -2,7 +2,6 @@ package webdav import ( "encoding/xml" - "fmt" "io" "net/http" "os" @@ -93,7 +92,7 @@ func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error { w.Header().Set("Last-Modified", fi.ModTime.UTC().Format(http.TimeFormat)) } if fi.ETag != "" { - w.Header().Set("ETag", fmt.Sprintf("%q", fi.ETag)) + w.Header().Set("ETag", internal.ETag(fi.ETag).String()) } if rs, ok := f.(io.ReadSeeker); ok { @@ -174,7 +173,7 @@ func (b *backend) propfindFile(propfind *internal.Propfind, fi *FileInfo) (*inte if fi.ETag != "" { props[internal.GetETagName] = func(*internal.RawXMLValue) (interface{}, error) { - return &internal.GetETag{ETag: fmt.Sprintf("%q", fi.ETag)}, nil + return &internal.GetETag{ETag: internal.ETag(fi.ETag)}, nil } } }