Commit 589db58a authored by Nigel Tao's avatar Nigel Tao

webdav: let DeadPropsHolder.DeadProps return an error.

A DeadPropsHolder could be backed by disk, whether directly or
indirectly via a database, so we should allow for I/O to fail.

Change-Id: Id40bcc86eb854212ef254ea1e1c54fd2a2b1960a
Reviewed-on: https://go-review.googlesource.com/10472Reviewed-by: 's avatarRobert Stepanek <robert.stepanek@gmail.com>
Reviewed-by: 's avatarNigel Tao <nigeltao@golang.org>
parent 6fbb23f9
...@@ -423,17 +423,17 @@ func (n *memFSNode) stat(name string) *memFileInfo { ...@@ -423,17 +423,17 @@ func (n *memFSNode) stat(name string) *memFileInfo {
} }
} }
func (n *memFSNode) DeadProps() map[xml.Name]Property { func (n *memFSNode) DeadProps() (map[xml.Name]Property, error) {
n.mu.Lock() n.mu.Lock()
defer n.mu.Unlock() defer n.mu.Unlock()
if len(n.deadProps) == 0 { if len(n.deadProps) == 0 {
return nil return nil, nil
} }
ret := make(map[xml.Name]Property, len(n.deadProps)) ret := make(map[xml.Name]Property, len(n.deadProps))
for k, v := range n.deadProps { for k, v := range n.deadProps {
ret[k] = v ret[k] = v
} }
return ret return ret, nil
} }
func (n *memFSNode) Patch(patches []Proppatch) ([]Propstat, error) { func (n *memFSNode) Patch(patches []Proppatch) ([]Propstat, error) {
...@@ -484,7 +484,7 @@ type memFile struct { ...@@ -484,7 +484,7 @@ type memFile struct {
// A *memFile implements the optional DeadPropsHolder interface. // A *memFile implements the optional DeadPropsHolder interface.
var _ DeadPropsHolder = (*memFile)(nil) var _ DeadPropsHolder = (*memFile)(nil)
func (f *memFile) DeadProps() map[xml.Name]Property { return f.n.DeadProps() } func (f *memFile) DeadProps() (map[xml.Name]Property, error) { return f.n.DeadProps() }
func (f *memFile) Patch(patches []Proppatch) ([]Propstat, error) { return f.n.Patch(patches) } func (f *memFile) Patch(patches []Proppatch) ([]Propstat, error) { return f.n.Patch(patches) }
func (f *memFile) Close() error { func (f *memFile) Close() error {
...@@ -626,6 +626,27 @@ func moveFiles(fs FileSystem, src, dst string, overwrite bool) (status int, err ...@@ -626,6 +626,27 @@ func moveFiles(fs FileSystem, src, dst string, overwrite bool) (status int, err
return http.StatusNoContent, nil return http.StatusNoContent, nil
} }
func copyProps(dst, src File) error {
d, ok := dst.(DeadPropsHolder)
if !ok {
return nil
}
s, ok := src.(DeadPropsHolder)
if !ok {
return nil
}
m, err := s.DeadProps()
if err != nil {
return err
}
props := make([]Property, 0, len(m))
for _, prop := range m {
props = append(props, prop)
}
_, err = d.Patch([]Proppatch{{Props: props}})
return err
}
// copyFiles copies files and/or directories from src to dst. // copyFiles copies files and/or directories from src to dst.
// //
// See section 9.8.5 for when various HTTP status codes apply. // See section 9.8.5 for when various HTTP status codes apply.
...@@ -702,17 +723,7 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs ...@@ -702,17 +723,7 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs
} }
_, copyErr := io.Copy(dstFile, srcFile) _, copyErr := io.Copy(dstFile, srcFile)
var propsErr error propsErr := copyProps(dstFile, srcFile)
if s, ok := srcFile.(DeadPropsHolder); ok {
if d, ok := dstFile.(DeadPropsHolder); ok {
m := s.DeadProps()
props := make([]Property, 0, len(m))
for _, prop := range m {
props = append(props, prop)
}
_, propsErr = d.Patch([]Proppatch{{Props: props}})
}
}
closeErr := dstFile.Close() closeErr := dstFile.Close()
if copyErr != nil { if copyErr != nil {
return http.StatusInternalServerError, copyErr return http.StatusInternalServerError, copyErr
......
...@@ -825,7 +825,7 @@ func BenchmarkMemFileWrite(b *testing.B) { ...@@ -825,7 +825,7 @@ func BenchmarkMemFileWrite(b *testing.B) {
} }
} }
func TestMoveCopyProps(t *testing.T) { func TestCopyMoveProps(t *testing.T) {
fs := NewMemFS() fs := NewMemFS()
create := func(name string) error { create := func(name string) error {
f, err := fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) f, err := fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
...@@ -856,8 +856,11 @@ func TestMoveCopyProps(t *testing.T) { ...@@ -856,8 +856,11 @@ func TestMoveCopyProps(t *testing.T) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
m := f.(DeadPropsHolder).DeadProps() m, pErr := f.(DeadPropsHolder).DeadProps()
cErr := f.Close() cErr := f.Close()
if pErr != nil {
return nil, pErr
}
if cErr != nil { if cErr != nil {
return nil, cErr return nil, cErr
} }
......
...@@ -80,7 +80,7 @@ func makePropstats(x, y Propstat) []Propstat { ...@@ -80,7 +80,7 @@ func makePropstats(x, y Propstat) []Propstat {
// method of DeadPropsHolder implementations. // method of DeadPropsHolder implementations.
type DeadPropsHolder interface { type DeadPropsHolder interface {
// DeadProps returns a copy of the dead properties held. // DeadProps returns a copy of the dead properties held.
DeadProps() map[xml.Name]Property DeadProps() (map[xml.Name]Property, error)
// Patch patches the dead properties held. // Patch patches the dead properties held.
// //
...@@ -166,7 +166,10 @@ func props(fs FileSystem, ls LockSystem, name string, pnames []xml.Name) ([]Prop ...@@ -166,7 +166,10 @@ func props(fs FileSystem, ls LockSystem, name string, pnames []xml.Name) ([]Prop
var deadProps map[xml.Name]Property var deadProps map[xml.Name]Property
if dph, ok := f.(DeadPropsHolder); ok { if dph, ok := f.(DeadPropsHolder); ok {
deadProps = dph.DeadProps() deadProps, err = dph.DeadProps()
if err != nil {
return nil, err
}
} }
pstatOK := Propstat{Status: http.StatusOK} pstatOK := Propstat{Status: http.StatusOK}
...@@ -211,7 +214,10 @@ func propnames(fs FileSystem, ls LockSystem, name string) ([]xml.Name, error) { ...@@ -211,7 +214,10 @@ func propnames(fs FileSystem, ls LockSystem, name string) ([]xml.Name, error) {
var deadProps map[xml.Name]Property var deadProps map[xml.Name]Property
if dph, ok := f.(DeadPropsHolder); ok { if dph, ok := f.(DeadPropsHolder); ok {
deadProps = dph.DeadProps() deadProps, err = dph.DeadProps()
if err != nil {
return nil, err
}
} }
pnames := make([]xml.Name, 0, len(liveProps)+len(deadProps)) pnames := make([]xml.Name, 0, len(liveProps)+len(deadProps))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment