aboutsummaryrefslogtreecommitdiff
path: root/weed/server/filer_server_handlers_write_autochunk.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/server/filer_server_handlers_write_autochunk.go')
-rw-r--r--weed/server/filer_server_handlers_write_autochunk.go70
1 files changed, 53 insertions, 17 deletions
diff --git a/weed/server/filer_server_handlers_write_autochunk.go b/weed/server/filer_server_handlers_write_autochunk.go
index 1c7ed0c3c..cce64f74d 100644
--- a/weed/server/filer_server_handlers_write_autochunk.go
+++ b/weed/server/filer_server_handlers_write_autochunk.go
@@ -5,8 +5,6 @@ import (
"context"
"errors"
"fmt"
- //"github.com/seaweedfs/seaweedfs/weed/s3api"
- "github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
"io"
"net/http"
"os"
@@ -19,6 +17,7 @@ import (
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/operation"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
+ "github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
"github.com/seaweedfs/seaweedfs/weed/storage/needle"
"github.com/seaweedfs/seaweedfs/weed/util"
)
@@ -49,7 +48,9 @@ func (fs *FilerServer) autoChunk(ctx context.Context, w http.ResponseWriter, r *
reply, md5bytes, err = fs.doPutAutoChunk(ctx, w, r, chunkSize, contentLength, so)
}
if err != nil {
- if strings.HasPrefix(err.Error(), "read input:") || err.Error() == io.ErrUnexpectedEOF.Error() {
+ if err.Error() == "operation not permitted" {
+ writeJsonError(w, r, http.StatusForbidden, err)
+ } else if strings.HasPrefix(err.Error(), "read input:") || err.Error() == io.ErrUnexpectedEOF.Error() {
writeJsonError(w, r, util.HttpStatusCancelled, err)
} else if strings.HasSuffix(err.Error(), "is a file") || strings.HasSuffix(err.Error(), "already exists") {
writeJsonError(w, r, http.StatusConflict, err)
@@ -85,6 +86,10 @@ func (fs *FilerServer) doPostAutoChunk(ctx context.Context, w http.ResponseWrite
contentType = ""
}
+ if err := fs.checkPermissions(ctx, r, fileName); err != nil {
+ return nil, nil, err
+ }
+
if so.SaveInside {
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()
@@ -121,6 +126,10 @@ func (fs *FilerServer) doPutAutoChunk(ctx context.Context, w http.ResponseWriter
contentType = ""
}
+ if err := fs.checkPermissions(ctx, r, ""); err != nil {
+ return nil, nil, err
+ }
+
fileChunks, md5Hash, chunkOffset, err, smallContent := fs.uploadReaderToChunks(w, r, r.Body, chunkSize, fileName, contentType, contentLength, so)
if err != nil {
return nil, nil, err
@@ -152,35 +161,62 @@ func isS3Request(r *http.Request) bool {
return r.Header.Get(s3_constants.AmzAuthType) != "" || r.Header.Get("X-Amz-Date") != ""
}
-func (fs *FilerServer) saveMetaData(ctx context.Context, r *http.Request, fileName string, contentType string, so *operation.StorageOption, md5bytes []byte, fileChunks []*filer_pb.FileChunk, chunkOffset int64, content []byte) (filerResult *FilerPostResult, replyerr error) {
-
- // detect file mode
- modeStr := r.URL.Query().Get("mode")
- if modeStr == "" {
- modeStr = "0660"
+func (fs *FilerServer) checkPermissions(ctx context.Context, r *http.Request, fileName string) error {
+ fullPath := fs.fixFilePath(ctx, r, fileName)
+ rule := fs.filer.FilerConf.MatchStorageRule(fullPath)
+ if !rule.Worm {
+ return nil
}
- mode, err := strconv.ParseUint(modeStr, 8, 32)
+
+ _, err := fs.filer.FindEntry(ctx, util.FullPath(fullPath))
if err != nil {
- glog.Errorf("Invalid mode format: %s, use 0660 by default", modeStr)
- mode = 0660
+ if errors.Is(err, filer_pb.ErrNotFound) {
+ return nil
+ }
+
+ return err
}
+ // you cannot change an existing file in Worm mode
+ return errors.New("operation not permitted")
+}
+
+func (fs *FilerServer) fixFilePath(ctx context.Context, r *http.Request, fileName string) string {
// fix the path
- path := r.URL.Path
- if strings.HasSuffix(path, "/") {
+ fullPath := r.URL.Path
+ if strings.HasSuffix(fullPath, "/") {
if fileName != "" {
- path += fileName
+ fullPath += fileName
}
} else {
if fileName != "" {
- if possibleDirEntry, findDirErr := fs.filer.FindEntry(ctx, util.FullPath(path)); findDirErr == nil {
+ if possibleDirEntry, findDirErr := fs.filer.FindEntry(ctx, util.FullPath(fullPath)); findDirErr == nil {
if possibleDirEntry.IsDirectory() {
- path += "/" + fileName
+ fullPath += "/" + fileName
}
}
}
}
+ return fullPath
+}
+
+func (fs *FilerServer) saveMetaData(ctx context.Context, r *http.Request, fileName string, contentType string, so *operation.StorageOption, md5bytes []byte, fileChunks []*filer_pb.FileChunk, chunkOffset int64, content []byte) (filerResult *FilerPostResult, replyerr error) {
+
+ // detect file mode
+ modeStr := r.URL.Query().Get("mode")
+ if modeStr == "" {
+ modeStr = "0660"
+ }
+ mode, err := strconv.ParseUint(modeStr, 8, 32)
+ if err != nil {
+ glog.Errorf("Invalid mode format: %s, use 0660 by default", modeStr)
+ mode = 0660
+ }
+
+ // fix the path
+ path := fs.fixFilePath(ctx, r, fileName)
+
var entry *filer.Entry
var newChunks []*filer_pb.FileChunk
var mergedChunks []*filer_pb.FileChunk