mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2025-04-05 20:52:50 +08:00
validate tags on copy object and add regex for validating tags
This commit is contained in:
parent
aaa9938353
commit
5f5fd0bc48
@ -45,7 +45,11 @@ func (s3a *S3ApiServer) CopyObjectHandler(w http.ResponseWriter, r *http.Request
|
|||||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidCopySource)
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidCopySource)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
entry.Extended = processMetadataBytes(r.Header, entry.Extended, replaceMeta, replaceTagging)
|
entry.Extended, err = processMetadataBytes(r.Header, entry.Extended, replaceMeta, replaceTagging)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("CopyObjectHandler ValidateTags error %s: %v", r.URL, err)
|
||||||
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
|
||||||
|
}
|
||||||
err = s3a.touch(dir, name, entry)
|
err = s3a.touch(dir, name, entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidCopySource)
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidCopySource)
|
||||||
@ -252,7 +256,7 @@ func processMetadata(reqHeader, existing http.Header, replaceMeta, replaceTaggin
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func processMetadataBytes(reqHeader http.Header, existing map[string][]byte, replaceMeta, replaceTagging bool) (metadata map[string][]byte) {
|
func processMetadataBytes(reqHeader http.Header, existing map[string][]byte, replaceMeta, replaceTagging bool) (metadata map[string][]byte, err error) {
|
||||||
metadata = make(map[string][]byte)
|
metadata = make(map[string][]byte)
|
||||||
|
|
||||||
if sc := existing[s3_constants.AmzStorageClass]; len(sc) > 0 {
|
if sc := existing[s3_constants.AmzStorageClass]; len(sc) > 0 {
|
||||||
@ -277,16 +281,18 @@ func processMetadataBytes(reqHeader http.Header, existing map[string][]byte, rep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if replaceTagging {
|
if replaceTagging {
|
||||||
if tags := reqHeader.Get(s3_constants.AmzObjectTagging); tags != "" {
|
if tags := reqHeader.Get(s3_constants.AmzObjectTagging); tags != "" {
|
||||||
for _, v := range strings.Split(tags, "&") {
|
parsedTags, err := parseTagsHeader(tags)
|
||||||
tag := strings.Split(v, "=")
|
if err != nil {
|
||||||
if len(tag) == 2 {
|
return nil, err
|
||||||
metadata[s3_constants.AmzObjectTagging+"-"+tag[0]] = []byte(tag[1])
|
}
|
||||||
} else if len(tag) == 1 {
|
err = validateTags(parsedTags)
|
||||||
metadata[s3_constants.AmzObjectTagging+"-"+tag[0]] = nil
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
|
}
|
||||||
|
for k, v := range parsedTags {
|
||||||
|
metadata[s3_constants.AmzObjectTagging+"-"+k] = []byte(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -367,7 +367,7 @@ func TestProcessMetadataBytes(t *testing.T) {
|
|||||||
reqHeader := transferHToHeader(tc.request)
|
reqHeader := transferHToHeader(tc.request)
|
||||||
existing := transferHToBytesArr(tc.existing)
|
existing := transferHToBytesArr(tc.existing)
|
||||||
replaceMeta, replaceTagging := replaceDirective(reqHeader)
|
replaceMeta, replaceTagging := replaceDirective(reqHeader)
|
||||||
extends := processMetadataBytes(reqHeader, existing, replaceMeta, replaceTagging)
|
extends, _ := processMetadataBytes(reqHeader, existing, replaceMeta, replaceTagging)
|
||||||
|
|
||||||
result := transferBytesArrToH(extends)
|
result := transferBytesArrToH(extends)
|
||||||
fmtTagging(result, tc.want)
|
fmtTagging(result, tc.want)
|
||||||
|
@ -62,22 +62,10 @@ func (s3a *S3ApiServer) PutObjectTaggingHandler(w http.ResponseWriter, r *http.R
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
tags := tagging.ToTags()
|
tags := tagging.ToTags()
|
||||||
if len(tags) > 10 {
|
err = validateTags(tags)
|
||||||
glog.Errorf("PutObjectTaggingHandler tags %s: %d tags more than 10", r.URL, len(tags))
|
if err != nil {
|
||||||
|
glog.Errorf("PutObjectTaggingHandler ValidateTags error %s: %v", r.URL, err)
|
||||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
|
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
|
||||||
return
|
|
||||||
}
|
|
||||||
for k, v := range tags {
|
|
||||||
if len(k) > 128 {
|
|
||||||
glog.Errorf("PutObjectTaggingHandler tags %s: tag key %s longer than 128", r.URL, k)
|
|
||||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(v) > 256 {
|
|
||||||
glog.Errorf("PutObjectTaggingHandler tags %s: tag value %s longer than 256", r.URL, v)
|
|
||||||
s3err.WriteErrorResponse(w, r, s3err.ErrInvalidTag)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = s3a.setTags(dir, name, tagging.ToTags()); err != nil {
|
if err = s3a.setTags(dir, name, tagging.ToTags()); err != nil {
|
||||||
|
@ -2,6 +2,9 @@ package s3api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Tag struct {
|
type Tag struct {
|
||||||
@ -37,3 +40,40 @@ func FromTags(tags map[string]string) (t *Tagging) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseTagsHeader(tags string) (map[string]string, error) {
|
||||||
|
var parsedTags map[string]string
|
||||||
|
for _, v := range strings.Split(tags, "&") {
|
||||||
|
tag := strings.Split(v, "=")
|
||||||
|
if len(tag) == 2 {
|
||||||
|
parsedTags[tag[0]] = tag[1]
|
||||||
|
} else if len(tag) == 1 {
|
||||||
|
parsedTags[tag[0]] = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateTags(tags map[string]string) error {
|
||||||
|
if len(tags) > 10 {
|
||||||
|
return fmt.Errorf("validate tags: %d tags more than 10", len(tags))
|
||||||
|
}
|
||||||
|
for k, v := range tags {
|
||||||
|
if len(k) > 128 {
|
||||||
|
return fmt.Errorf("validate tags: tag key %s longer than 128", k)
|
||||||
|
}
|
||||||
|
validateKey, err := regexp.MatchString(`^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$`, k)
|
||||||
|
if !validateKey && err != nil {
|
||||||
|
return fmt.Errorf("validate tags key %s error %w ", k, err)
|
||||||
|
}
|
||||||
|
if len(v) > 256 {
|
||||||
|
return fmt.Errorf("validate tags: tag value %s longer than 256", v)
|
||||||
|
}
|
||||||
|
validateValue, err := regexp.MatchString(`^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$`, v)
|
||||||
|
if !validateValue && err != nil {
|
||||||
|
return fmt.Errorf("validate tags value %s error %w ", v, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user