2020-10-03 05:21:51 +00:00
|
|
|
package s3api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/xml"
|
|
|
|
"fmt"
|
2021-10-14 04:27:58 +00:00
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
|
2020-10-03 05:21:51 +00:00
|
|
|
"github.com/chrislusf/seaweedfs/weed/glog"
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/s3api/s3err"
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/util"
|
|
|
|
)
|
|
|
|
|
|
|
|
// GetObjectTaggingHandler - GET object tagging
|
|
|
|
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html
|
|
|
|
func (s3a *S3ApiServer) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
bucket, object := getBucketAndObject(r)
|
2021-09-19 07:18:59 +00:00
|
|
|
glog.V(3).Infof("GetObjectTaggingHandler %s %s", bucket, object)
|
2020-10-03 05:21:51 +00:00
|
|
|
|
|
|
|
target := util.FullPath(fmt.Sprintf("%s/%s%s", s3a.option.BucketsPath, bucket, object))
|
|
|
|
dir, name := target.DirAndName()
|
|
|
|
|
|
|
|
tags, err := s3a.getTags(dir, name)
|
|
|
|
if err != nil {
|
|
|
|
if err == filer_pb.ErrNotFound {
|
|
|
|
glog.Errorf("GetObjectTaggingHandler %s: %v", r.URL, err)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchKey)
|
2020-10-03 05:21:51 +00:00
|
|
|
} else {
|
|
|
|
glog.Errorf("GetObjectTaggingHandler %s: %v", r.URL, err)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
2020-10-03 05:21:51 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-11-01 01:02:08 +00:00
|
|
|
writeSuccessResponseXML(w, r, FromTags(tags))
|
2020-10-03 05:21:51 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// PutObjectTaggingHandler Put object tagging
|
|
|
|
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html
|
|
|
|
func (s3a *S3ApiServer) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
bucket, object := getBucketAndObject(r)
|
2021-09-19 07:18:59 +00:00
|
|
|
glog.V(3).Infof("PutObjectTaggingHandler %s %s", bucket, object)
|
2020-10-03 05:21:51 +00:00
|
|
|
|
|
|
|
target := util.FullPath(fmt.Sprintf("%s/%s%s", s3a.option.BucketsPath, bucket, object))
|
|
|
|
dir, name := target.DirAndName()
|
|
|
|
|
|
|
|
tagging := &Tagging{}
|
2021-10-14 04:27:58 +00:00
|
|
|
input, err := io.ReadAll(io.LimitReader(r.Body, r.ContentLength))
|
2020-10-03 05:21:51 +00:00
|
|
|
if err != nil {
|
|
|
|
glog.Errorf("PutObjectTaggingHandler read input %s: %v", r.URL, err)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
2020-10-03 05:21:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if err = xml.Unmarshal(input, tagging); err != nil {
|
|
|
|
glog.Errorf("PutObjectTaggingHandler Unmarshal %s: %v", r.URL, err)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrMalformedXML)
|
2020-10-03 05:21:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
tags := tagging.ToTags()
|
|
|
|
if len(tags) > 10 {
|
|
|
|
glog.Errorf("PutObjectTaggingHandler tags %s: %d tags more than 10", r.URL, len(tags))
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
|
2020-10-03 05:21:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
for k, v := range tags {
|
|
|
|
if len(k) > 128 {
|
|
|
|
glog.Errorf("PutObjectTaggingHandler tags %s: tag key %s longer than 128", r.URL, k)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
|
2020-10-03 05:21:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if len(v) > 256 {
|
|
|
|
glog.Errorf("PutObjectTaggingHandler tags %s: tag value %s longer than 256", r.URL, v)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
|
2020-10-03 05:21:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = s3a.setTags(dir, name, tagging.ToTags()); err != nil {
|
|
|
|
if err == filer_pb.ErrNotFound {
|
|
|
|
glog.Errorf("PutObjectTaggingHandler setTags %s: %v", r.URL, err)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchKey)
|
2020-10-03 05:21:51 +00:00
|
|
|
} else {
|
|
|
|
glog.Errorf("PutObjectTaggingHandler setTags %s: %v", r.URL, err)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
2020-10-03 05:21:51 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-10-20 11:01:06 +00:00
|
|
|
w.WriteHeader(http.StatusOK)
|
2020-10-03 05:21:51 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteObjectTaggingHandler Delete object tagging
|
|
|
|
// API reference: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html
|
|
|
|
func (s3a *S3ApiServer) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
bucket, object := getBucketAndObject(r)
|
2021-09-19 07:18:59 +00:00
|
|
|
glog.V(3).Infof("DeleteObjectTaggingHandler %s %s", bucket, object)
|
2020-10-03 05:21:51 +00:00
|
|
|
|
|
|
|
target := util.FullPath(fmt.Sprintf("%s/%s%s", s3a.option.BucketsPath, bucket, object))
|
|
|
|
dir, name := target.DirAndName()
|
|
|
|
|
|
|
|
err := s3a.rmTags(dir, name)
|
|
|
|
if err != nil {
|
|
|
|
if err == filer_pb.ErrNotFound {
|
|
|
|
glog.Errorf("DeleteObjectTaggingHandler %s: %v", r.URL, err)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchKey)
|
2020-10-03 05:21:51 +00:00
|
|
|
} else {
|
|
|
|
glog.Errorf("DeleteObjectTaggingHandler %s: %v", r.URL, err)
|
2021-11-01 01:05:34 +00:00
|
|
|
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
2020-10-03 05:21:51 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
}
|