carddav: pass If-(None-)Match to backend

This simply extends the interfaces to pass on the values if they were
used, relying on the backend to handle things accordingly.
This commit is contained in:
Conrad Hoffmann 2022-03-17 11:19:51 +01:00 committed by Simon Ser
parent 52215c1690
commit c4206ba616

View File

@ -14,13 +14,22 @@ import (
// TODO: add support for multiple address books // TODO: add support for multiple address books
type PutAddressObjectOptions struct {
// IfNoneMatch indicates that the client does not want to overwrite
// an existing resource.
IfNoneMatch bool
// IfMatch provides the ETag of the resource that the client intends
// to overwrite, can be ""
IfMatch string
}
// Backend is a CardDAV server backend. // Backend is a CardDAV server backend.
type Backend interface { type Backend interface {
AddressBook(ctx context.Context) (*AddressBook, error) AddressBook(ctx context.Context) (*AddressBook, error)
GetAddressObject(ctx context.Context, path string, req *AddressDataRequest) (*AddressObject, error) GetAddressObject(ctx context.Context, path string, req *AddressDataRequest) (*AddressObject, error)
ListAddressObjects(ctx context.Context, req *AddressDataRequest) ([]AddressObject, error) ListAddressObjects(ctx context.Context, req *AddressDataRequest) ([]AddressObject, error)
QueryAddressObjects(ctx context.Context, query *AddressBookQuery) ([]AddressObject, error) QueryAddressObjects(ctx context.Context, query *AddressBookQuery) ([]AddressObject, error)
PutAddressObject(ctx context.Context, path string, card vcard.Card) (loc string, err error) PutAddressObject(ctx context.Context, path string, card vcard.Card, opts *PutAddressObjectOptions) (loc string, err error)
DeleteAddressObject(ctx context.Context, path string) error DeleteAddressObject(ctx context.Context, path string) error
} }
@ -397,7 +406,14 @@ func (b *backend) Proppatch(r *http.Request, update *internal.Propertyupdate) (*
} }
func (b *backend) Put(r *http.Request) (*internal.Href, error) { func (b *backend) Put(r *http.Request) (*internal.Href, error) {
// TODO: add support for If-None-Match and If-Match if inm := r.Header.Get("If-None-Match"); inm != "" && inm != "*" {
return nil, internal.HTTPErrorf(http.StatusBadRequest, "invalid value for If-None-Match header")
}
opts := PutAddressObjectOptions{
IfNoneMatch: r.Header.Get("If-None-Match") == "*",
IfMatch: r.Header.Get("If-Match"),
}
t, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) t, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
if err != nil { if err != nil {
@ -416,7 +432,7 @@ func (b *backend) Put(r *http.Request) (*internal.Href, error) {
} }
// TODO: add support for the CARDDAV:no-uid-conflict error // TODO: add support for the CARDDAV:no-uid-conflict error
loc, err := b.Backend.PutAddressObject(r.Context(), r.URL.Path, card) loc, err := b.Backend.PutAddressObject(r.Context(), r.URL.Path, card, &opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }