internal: add ETag

This commit is contained in:
Simon Ser 2020-02-03 21:48:31 +01:00
parent ca51e9427a
commit 25678476db
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
6 changed files with 26 additions and 23 deletions

View File

@ -3,7 +3,6 @@ package caldav
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"strconv"
"time" "time"
"github.com/emersion/go-webdav" "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) { if err := resp.DecodeProp(&getETag); err != nil && !internal.IsNotFound(err) {
return nil, 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{ addrs = append(addrs, CalendarObject{
Path: path, Path: path,
ModTime: time.Time(getLastMod.LastModified), ModTime: time.Time(getLastMod.LastModified),
ETag: etag, ETag: string(getETag.ETag),
Data: calData.Data, Data: calData.Data,
}) })
} }

View File

@ -6,7 +6,6 @@ import (
"net" "net"
"net/http" "net/http"
"net/url" "net/url"
"strconv"
"strings" "strings"
"time" "time"
@ -222,10 +221,6 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
if err := resp.DecodeProp(&getETag); err != nil && !internal.IsNotFound(err) { if err := resp.DecodeProp(&getETag); err != nil && !internal.IsNotFound(err) {
return nil, 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) r := bytes.NewReader(addrData.Data)
card, err := vcard.NewDecoder(r).Decode() card, err := vcard.NewDecoder(r).Decode()
@ -236,7 +231,7 @@ func decodeAddressList(ms *internal.Multistatus) ([]AddressObject, error) {
addrs = append(addrs, AddressObject{ addrs = append(addrs, AddressObject{
Path: path, Path: path,
ModTime: time.Time(getLastMod.LastModified), ModTime: time.Time(getLastMod.LastModified),
ETag: etag, ETag: string(getETag.ETag),
Card: card, Card: card,
}) })
} }

View File

@ -372,7 +372,7 @@ func (b *backend) propfindAddressObject(propfind *internal.Propfind, ao *Address
if ao.ETag != "" { if ao.ETag != "" {
props[internal.GetETagName] = func(*internal.RawXMLValue) (interface{}, error) { 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
} }
} }

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"strconv"
"time" "time"
"github.com/emersion/go-webdav/internal" "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) { if err := resp.DecodeProp(&getETag); err != nil && !internal.IsNotFound(err) {
return nil, 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.Size = getLen.Length
fi.ModTime = time.Time(getMod.LastModified) fi.ModTime = time.Time(getMod.LastModified)
fi.MIMEType = getType.Type fi.MIMEType = getType.Type
fi.ETag = etag fi.ETag = string(getETag.ETag)
} }
return fi, nil return fi, nil

View File

@ -342,7 +342,26 @@ type GetLastModified struct {
// https://tools.ietf.org/html/rfc4918#section-15.6 // https://tools.ietf.org/html/rfc4918#section-15.6
type GetETag struct { type GetETag struct {
XMLName xml.Name `xml:"DAV: getetag"` 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 // https://tools.ietf.org/html/rfc4918#section-14.5

View File

@ -2,7 +2,6 @@ package webdav
import ( import (
"encoding/xml" "encoding/xml"
"fmt"
"io" "io"
"net/http" "net/http"
"os" "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)) w.Header().Set("Last-Modified", fi.ModTime.UTC().Format(http.TimeFormat))
} }
if fi.ETag != "" { 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 { if rs, ok := f.(io.ReadSeeker); ok {
@ -174,7 +173,7 @@ func (b *backend) propfindFile(propfind *internal.Propfind, fi *FileInfo) (*inte
if fi.ETag != "" { if fi.ETag != "" {
props[internal.GetETagName] = func(*internal.RawXMLValue) (interface{}, error) { 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
} }
} }
} }