tags.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package s3api
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. "github.com/seaweedfs/seaweedfs/weed/util"
  6. "regexp"
  7. "sort"
  8. "strings"
  9. )
  10. type Tag struct {
  11. Key string `xml:"Key"`
  12. Value string `xml:"Value"`
  13. }
  14. type TagSet struct {
  15. Tag []Tag `xml:"Tag"`
  16. }
  17. type Tagging struct {
  18. XMLName xml.Name `xml:"Tagging"`
  19. TagSet TagSet `xml:"TagSet"`
  20. Xmlns string `xml:"xmlns,attr"`
  21. }
  22. func (t *Tagging) ToTags() map[string]string {
  23. output := make(map[string]string)
  24. for _, tag := range t.TagSet.Tag {
  25. output[tag.Key] = tag.Value
  26. }
  27. return output
  28. }
  29. func FromTags(tags map[string]string) (t *Tagging) {
  30. t = &Tagging{Xmlns: "http://s3.amazonaws.com/doc/2006-03-01/"}
  31. for k, v := range tags {
  32. t.TagSet.Tag = append(t.TagSet.Tag, Tag{
  33. Key: k,
  34. Value: v,
  35. })
  36. }
  37. if tagArr := t.TagSet.Tag; len(tagArr) > 0 {
  38. sort.SliceStable(tagArr, func(i, j int) bool {
  39. return tagArr[i].Key < tagArr[j].Key
  40. })
  41. }
  42. return
  43. }
  44. func parseTagsHeader(tags string) (map[string]string, error) {
  45. parsedTags := make(map[string]string)
  46. for _, v := range util.StringSplit(tags, "&") {
  47. tag := strings.Split(v, "=")
  48. if len(tag) == 2 {
  49. parsedTags[tag[0]] = tag[1]
  50. } else if len(tag) == 1 {
  51. parsedTags[tag[0]] = ""
  52. }
  53. }
  54. return parsedTags, nil
  55. }
  56. func ValidateTags(tags map[string]string) error {
  57. if len(tags) > 10 {
  58. return fmt.Errorf("validate tags: %d tags more than 10", len(tags))
  59. }
  60. for k, v := range tags {
  61. if len(k) > 128 {
  62. return fmt.Errorf("validate tags: tag key longer than 128")
  63. }
  64. validateKey, err := regexp.MatchString(`^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$`, k)
  65. if !validateKey || err != nil {
  66. return fmt.Errorf("validate tags key %s error, incorrect key", k)
  67. }
  68. if len(v) > 256 {
  69. return fmt.Errorf("validate tags: tag value longer than 256")
  70. }
  71. validateValue, err := regexp.MatchString(`^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$`, v)
  72. if !validateValue || err != nil {
  73. return fmt.Errorf("validate tags value %s error, incorrect value", v)
  74. }
  75. }
  76. return nil
  77. }