Commit 6fbb23f9 authored by Nigel Tao's avatar Nigel Tao

webdav: have copyFiles copy dead properties.

Change-Id: I778e26c06f153fb705b450052d3721fec9a3082b
Reviewed-on: https://go-review.googlesource.com/10471Reviewed-by: 's avatarRobert Stepanek <robert.stepanek@gmail.com>
Reviewed-by: 's avatarNigel Tao <nigeltao@golang.org>
parent 610bfeeb
...@@ -702,10 +702,24 @@ func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recurs ...@@ -702,10 +702,24 @@ 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
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
} }
if propsErr != nil {
return http.StatusInternalServerError, propsErr
}
if closeErr != nil { if closeErr != nil {
return http.StatusInternalServerError, closeErr return http.StatusInternalServerError, closeErr
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package webdav package webdav
import ( import (
"encoding/xml"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
...@@ -824,6 +825,112 @@ func BenchmarkMemFileWrite(b *testing.B) { ...@@ -824,6 +825,112 @@ func BenchmarkMemFileWrite(b *testing.B) {
} }
} }
func TestMoveCopyProps(t *testing.T) {
fs := NewMemFS()
create := func(name string) error {
f, err := fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return err
}
_, wErr := f.Write([]byte("contents"))
cErr := f.Close()
if wErr != nil {
return wErr
}
return cErr
}
patch := func(name string, patches ...Proppatch) error {
f, err := fs.OpenFile(name, os.O_RDWR, 0666)
if err != nil {
return err
}
_, pErr := f.(DeadPropsHolder).Patch(patches)
cErr := f.Close()
if pErr != nil {
return pErr
}
return cErr
}
props := func(name string) (map[xml.Name]Property, error) {
f, err := fs.OpenFile(name, os.O_RDWR, 0666)
if err != nil {
return nil, err
}
m := f.(DeadPropsHolder).DeadProps()
cErr := f.Close()
if cErr != nil {
return nil, cErr
}
return m, nil
}
p0 := Property{
XMLName: xml.Name{Space: "x:", Local: "boat"},
InnerXML: []byte("pea-green"),
}
p1 := Property{
XMLName: xml.Name{Space: "x:", Local: "ring"},
InnerXML: []byte("1 shilling"),
}
p2 := Property{
XMLName: xml.Name{Space: "x:", Local: "spoon"},
InnerXML: []byte("runcible"),
}
p3 := Property{
XMLName: xml.Name{Space: "x:", Local: "moon"},
InnerXML: []byte("light"),
}
if err := create("/src"); err != nil {
t.Fatalf("create /src: %v", err)
}
if err := patch("/src", Proppatch{Props: []Property{p0, p1}}); err != nil {
t.Fatalf("patch /src +p0 +p1: %v", err)
}
if _, err := copyFiles(fs, "/src", "/tmp", true, infiniteDepth, 0); err != nil {
t.Fatalf("copyFiles /src /tmp: %v", err)
}
if _, err := moveFiles(fs, "/tmp", "/dst", true); err != nil {
t.Fatalf("moveFiles /tmp /dst: %v", err)
}
if err := patch("/src", Proppatch{Props: []Property{p0}, Remove: true}); err != nil {
t.Fatalf("patch /src -p0: %v", err)
}
if err := patch("/src", Proppatch{Props: []Property{p2}}); err != nil {
t.Fatalf("patch /src +p2: %v", err)
}
if err := patch("/dst", Proppatch{Props: []Property{p1}, Remove: true}); err != nil {
t.Fatalf("patch /dst -p1: %v", err)
}
if err := patch("/dst", Proppatch{Props: []Property{p3}}); err != nil {
t.Fatalf("patch /dst +p3: %v", err)
}
gotSrc, err := props("/src")
if err != nil {
t.Fatalf("props /src: %v", err)
}
wantSrc := map[xml.Name]Property{
p1.XMLName: p1,
p2.XMLName: p2,
}
if !reflect.DeepEqual(gotSrc, wantSrc) {
t.Fatalf("props /src:\ngot %v\nwant %v", gotSrc, wantSrc)
}
gotDst, err := props("/dst")
if err != nil {
t.Fatalf("props /dst: %v", err)
}
wantDst := map[xml.Name]Property{
p0.XMLName: p0,
p3.XMLName: p3,
}
if !reflect.DeepEqual(gotDst, wantDst) {
t.Fatalf("props /dst:\ngot %v\nwant %v", gotDst, wantDst)
}
}
func TestWalkFS(t *testing.T) { func TestWalkFS(t *testing.T) {
testCases := []struct { testCases := []struct {
desc string desc string
......
...@@ -292,8 +292,6 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request) (status in ...@@ -292,8 +292,6 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request) (status in
} }
func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status int, err error) { func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status int, err error) {
// TODO: COPY/MOVE for Properties, as per sections 9.8.2 and 9.9.1.
hdr := r.Header.Get("Destination") hdr := r.Header.Get("Destination")
if hdr == "" { if hdr == "" {
return http.StatusBadRequest, errInvalidDestination return http.StatusBadRequest, errInvalidDestination
......
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