You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
4.1 KiB

7 years ago
7 years ago
7 years ago
7 years ago
  1. package s3api
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "time"
  8. "github.com/chrislusf/seaweedfs/weed/glog"
  9. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  10. "github.com/gorilla/mux"
  11. )
  12. var (
  13. OS_UID = uint32(os.Getuid())
  14. OS_GID = uint32(os.Getgid())
  15. )
  16. func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
  17. var response ListAllMyBucketsResponse
  18. err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  19. request := &filer_pb.ListEntriesRequest{
  20. Directory: s3a.option.BucketsPath,
  21. }
  22. glog.V(4).Infof("read directory: %v", request)
  23. resp, err := client.ListEntries(context.Background(), request)
  24. if err != nil {
  25. return fmt.Errorf("list buckets: %v", err)
  26. }
  27. var buckets []ListAllMyBucketsEntry
  28. for _, entry := range resp.Entries {
  29. if entry.IsDirectory {
  30. buckets = append(buckets, ListAllMyBucketsEntry{
  31. Name: entry.Name,
  32. CreationDate: time.Unix(entry.Attributes.Crtime, 0),
  33. })
  34. }
  35. }
  36. response = ListAllMyBucketsResponse{
  37. ListAllMyBucketsResponse: ListAllMyBucketsResult{
  38. Owner: CanonicalUser{
  39. ID: "",
  40. DisplayName: "",
  41. },
  42. Buckets: ListAllMyBucketsList{
  43. Bucket: buckets,
  44. },
  45. },
  46. }
  47. return nil
  48. })
  49. if err != nil {
  50. writeErrorResponse(w, ErrInternalError, r.URL)
  51. return
  52. }
  53. writeSuccessResponseXML(w, encodeResponse(response))
  54. }
  55. func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request) {
  56. vars := mux.Vars(r)
  57. bucket := vars["bucket"]
  58. err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  59. request := &filer_pb.CreateEntryRequest{
  60. Directory: s3a.option.BucketsPath,
  61. Entry: &filer_pb.Entry{
  62. Name: bucket,
  63. IsDirectory: true,
  64. Attributes: &filer_pb.FuseAttributes{
  65. Mtime: time.Now().Unix(),
  66. Crtime: time.Now().Unix(),
  67. FileMode: uint32(0777 | os.ModeDir),
  68. Uid: OS_UID,
  69. Gid: OS_GID,
  70. },
  71. },
  72. }
  73. glog.V(1).Infof("create bucket: %v", request)
  74. if _, err := client.CreateEntry(context.Background(), request); err != nil {
  75. return fmt.Errorf("mkdir %s/%s: %v", s3a.option.BucketsPath, bucket, err)
  76. }
  77. // lazily create collection
  78. return nil
  79. })
  80. if err != nil {
  81. writeErrorResponse(w, ErrInternalError, r.URL)
  82. return
  83. }
  84. writeSuccessResponseEmpty(w)
  85. }
  86. func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
  87. vars := mux.Vars(r)
  88. bucket := vars["bucket"]
  89. err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  90. ctx := context.Background()
  91. // delete collection
  92. deleteCollectionRequest := &filer_pb.DeleteCollectionRequest{
  93. Collection: bucket,
  94. }
  95. glog.V(1).Infof("delete collection: %v", deleteCollectionRequest)
  96. if _, err := client.DeleteCollection(ctx, deleteCollectionRequest); err != nil {
  97. return fmt.Errorf("delete collection %s: %v", bucket, err)
  98. }
  99. // delete bucket metadata
  100. request := &filer_pb.DeleteEntryRequest{
  101. Directory: s3a.option.BucketsPath,
  102. Name: bucket,
  103. IsDirectory: true,
  104. IsDeleteData: false,
  105. IsRecursive: true,
  106. }
  107. glog.V(1).Infof("delete bucket: %v", request)
  108. if _, err := client.DeleteEntry(ctx, request); err != nil {
  109. return fmt.Errorf("delete bucket %s/%s: %v", s3a.option.BucketsPath, bucket, err)
  110. }
  111. return nil
  112. })
  113. if err != nil {
  114. writeErrorResponse(w, ErrInternalError, r.URL)
  115. return
  116. }
  117. writeResponse(w, http.StatusNoContent, nil, mimeNone)
  118. }
  119. func (s3a *S3ApiServer) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
  120. vars := mux.Vars(r)
  121. bucket := vars["bucket"]
  122. err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  123. request := &filer_pb.LookupDirectoryEntryRequest{
  124. Directory: s3a.option.BucketsPath,
  125. Name: bucket,
  126. }
  127. glog.V(1).Infof("lookup bucket: %v", request)
  128. if _, err := client.LookupDirectoryEntry(context.Background(), request); err != nil {
  129. return fmt.Errorf("lookup bucket %s/%s: %v", s3a.option.BucketsPath, bucket, err)
  130. }
  131. return nil
  132. })
  133. if err != nil {
  134. writeErrorResponse(w, ErrNoSuchBucket, r.URL)
  135. return
  136. }
  137. writeSuccessResponseEmpty(w)
  138. }