webdav: factor out a moveFiles function, and make the tests call that
instead of FileSystem.Rename directly.

Dir.Rename's behavior wrt overwriting existing files and directories is
OS-dependent.

Fixes golang/go#9786

Change-Id: If42728caa6f0f38f8e3d6b1fcdda8c2d272080d6
Reviewed-on: https://go-review.googlesource.com/4341
Reviewed-by: Nick Cooper <nmvc@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
diff --git a/webdav/webdav.go b/webdav/webdav.go
index 7776fbf..34a872c 100644
--- a/webdav/webdav.go
+++ b/webdav/webdav.go
@@ -247,36 +247,7 @@
 			return http.StatusBadRequest, errInvalidDepth
 		}
 	}
-
-	created := false
-	if _, err := h.FileSystem.Stat(dst); err != nil {
-		if !os.IsNotExist(err) {
-			return http.StatusForbidden, err
-		}
-		created = true
-	} else {
-		switch r.Header.Get("Overwrite") {
-		case "T":
-			// Section 9.9.3 says that "If a resource exists at the destination
-			// and the Overwrite header is "T", then prior to performing the move,
-			// the server must perform a DELETE with "Depth: infinity" on the
-			// destination resource.
-			if err := h.FileSystem.RemoveAll(dst); err != nil {
-				return http.StatusForbidden, err
-			}
-		case "F":
-			return http.StatusPreconditionFailed, os.ErrExist
-		default:
-			return http.StatusBadRequest, errInvalidOverwrite
-		}
-	}
-	if err := h.FileSystem.Rename(src, dst); err != nil {
-		return http.StatusForbidden, err
-	}
-	if created {
-		return http.StatusCreated, nil
-	}
-	return http.StatusNoContent, nil
+	return moveFiles(h.FileSystem, src, dst, r.Header.Get("Overwrite") == "T")
 }
 
 func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus int, retErr error) {
@@ -450,7 +421,6 @@
 	errInvalidIfHeader         = errors.New("webdav: invalid If header")
 	errInvalidLockInfo         = errors.New("webdav: invalid lock info")
 	errInvalidLockToken        = errors.New("webdav: invalid lock token")
-	errInvalidOverwrite        = errors.New("webdav: invalid overwrite")
 	errInvalidPropfind         = errors.New("webdav: invalid propfind")
 	errInvalidResponse         = errors.New("webdav: invalid response")
 	errInvalidTimeout          = errors.New("webdav: invalid timeout")