|
|
@ -3,6 +3,7 @@ package weed_server |
|
|
|
import ( |
|
|
|
"context" |
|
|
|
"errors" |
|
|
|
"fmt" |
|
|
|
"net/http" |
|
|
|
"os" |
|
|
|
"strings" |
|
|
@ -78,11 +79,78 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request, conte |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
fs.autoChunk(ctx, w, r, contentLength, so) |
|
|
|
if query.Has("from") { |
|
|
|
fs.move(ctx, w, r, so) |
|
|
|
} else { |
|
|
|
fs.autoChunk(ctx, w, r, contentLength, so) |
|
|
|
} |
|
|
|
|
|
|
|
util.CloseRequest(r) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
func (fs *FilerServer) move(ctx context.Context, w http.ResponseWriter, r *http.Request, so *operation.StorageOption) { |
|
|
|
src := r.URL.Query().Get("from") |
|
|
|
dst := r.URL.Path |
|
|
|
|
|
|
|
glog.V(2).Infof("FilerServer.move %v to %v", src, dst) |
|
|
|
|
|
|
|
var err error |
|
|
|
if src, err = clearName(src); err != nil { |
|
|
|
writeJsonError(w, r, http.StatusBadRequest, err) |
|
|
|
return |
|
|
|
} |
|
|
|
if dst, err = clearName(dst); err != nil { |
|
|
|
writeJsonError(w, r, http.StatusBadRequest, err) |
|
|
|
return |
|
|
|
} |
|
|
|
src = strings.TrimRight(src, "/") |
|
|
|
if src == "" { |
|
|
|
err = fmt.Errorf("invalid source '/'") |
|
|
|
writeJsonError(w, r, http.StatusBadRequest, err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
srcPath := util.FullPath(src) |
|
|
|
dstPath := util.FullPath(dst) |
|
|
|
srcEntry, err := fs.filer.FindEntry(ctx, srcPath) |
|
|
|
if err != nil { |
|
|
|
err = fmt.Errorf("failed to get src entry '%s', err: %s", src, err) |
|
|
|
writeJsonError(w, r, http.StatusBadRequest, err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
oldDir, oldName := srcPath.DirAndName() |
|
|
|
newDir, newName := dstPath.DirAndName() |
|
|
|
newName = util.Nvl(newName, oldName) |
|
|
|
|
|
|
|
dstEntry, err := fs.filer.FindEntry(ctx, util.FullPath(strings.TrimRight(dst, "/"))) |
|
|
|
if err != nil && err != filer_pb.ErrNotFound { |
|
|
|
err = fmt.Errorf("failed to get dst entry '%s', err: %s", dst, err) |
|
|
|
writeJsonError(w, r, http.StatusInternalServerError, err) |
|
|
|
return |
|
|
|
} |
|
|
|
if err == nil && !dstEntry.IsDirectory() && srcEntry.IsDirectory() { |
|
|
|
err = fmt.Errorf("move: cannot overwrite non-directory '%s' with directory '%s'", dst, src) |
|
|
|
writeJsonError(w, r, http.StatusBadRequest, err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
_, err = fs.AtomicRenameEntry(ctx, &filer_pb.AtomicRenameEntryRequest{ |
|
|
|
OldDirectory: oldDir, |
|
|
|
OldName: oldName, |
|
|
|
NewDirectory: newDir, |
|
|
|
NewName: newName, |
|
|
|
}) |
|
|
|
if err != nil { |
|
|
|
err = fmt.Errorf("failed to move entry from '%s' to '%s', err: %s", src, dst, err) |
|
|
|
writeJsonError(w, r, http.StatusBadRequest, err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
w.WriteHeader(http.StatusNoContent) |
|
|
|
} |
|
|
|
|
|
|
|
// curl -X DELETE http://localhost:8888/path/to
|
|
|
|
// curl -X DELETE http://localhost:8888/path/to?recursive=true
|
|
|
|
// curl -X DELETE http://localhost:8888/path/to?recursive=true&ignoreRecursiveError=true
|
|
|
|