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.

126 lines
3.0 KiB

7 years ago
7 years ago
7 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
4 years ago
6 years ago
4 years ago
5 years ago
7 years ago
4 years ago
7 years ago
5 years ago
7 years ago
7 years ago
  1. package s3api
  2. import (
  3. "context"
  4. "encoding/xml"
  5. "fmt"
  6. "math"
  7. "net/http"
  8. "time"
  9. "github.com/aws/aws-sdk-go/aws"
  10. "github.com/aws/aws-sdk-go/service/s3"
  11. "github.com/chrislusf/seaweedfs/weed/glog"
  12. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  13. )
  14. type ListAllMyBucketsResult struct {
  15. XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResult"`
  16. Owner *s3.Owner
  17. Buckets []*s3.Bucket `xml:"Buckets>Bucket"`
  18. }
  19. func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
  20. var response ListAllMyBucketsResult
  21. entries, err := s3a.list(s3a.option.BucketsPath, "", "", false, math.MaxInt32)
  22. if err != nil {
  23. writeErrorResponse(w, ErrInternalError, r.URL)
  24. return
  25. }
  26. var buckets []*s3.Bucket
  27. for _, entry := range entries {
  28. if entry.IsDirectory {
  29. buckets = append(buckets, &s3.Bucket{
  30. Name: aws.String(entry.Name),
  31. CreationDate: aws.Time(time.Unix(entry.Attributes.Crtime, 0).UTC()),
  32. })
  33. }
  34. }
  35. response = ListAllMyBucketsResult{
  36. Owner: &s3.Owner{
  37. ID: aws.String(""),
  38. DisplayName: aws.String(""),
  39. },
  40. Buckets: buckets,
  41. }
  42. writeSuccessResponseXML(w, encodeResponse(response))
  43. }
  44. func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request) {
  45. bucket, _ := getBucketAndObject(r)
  46. // create the folder for bucket, but lazily create actual collection
  47. if err := s3a.mkdir(s3a.option.BucketsPath, bucket, nil); err != nil {
  48. writeErrorResponse(w, ErrInternalError, r.URL)
  49. return
  50. }
  51. writeSuccessResponseEmpty(w)
  52. }
  53. func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
  54. bucket, _ := getBucketAndObject(r)
  55. err := s3a.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  56. // delete collection
  57. deleteCollectionRequest := &filer_pb.DeleteCollectionRequest{
  58. Collection: bucket,
  59. }
  60. glog.V(1).Infof("delete collection: %v", deleteCollectionRequest)
  61. if _, err := client.DeleteCollection(context.Background(), deleteCollectionRequest); err != nil {
  62. return fmt.Errorf("delete collection %s: %v", bucket, err)
  63. }
  64. return nil
  65. })
  66. err = s3a.rm(s3a.option.BucketsPath, bucket, false, true)
  67. if err != nil {
  68. writeErrorResponse(w, ErrInternalError, r.URL)
  69. return
  70. }
  71. writeResponse(w, http.StatusNoContent, nil, mimeNone)
  72. }
  73. func (s3a *S3ApiServer) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
  74. bucket, _ := getBucketAndObject(r)
  75. err := s3a.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  76. request := &filer_pb.LookupDirectoryEntryRequest{
  77. Directory: s3a.option.BucketsPath,
  78. Name: bucket,
  79. }
  80. glog.V(1).Infof("lookup bucket: %v", request)
  81. if _, err := filer_pb.LookupEntry(client, request); err != nil {
  82. if err == filer_pb.ErrNotFound {
  83. return filer_pb.ErrNotFound
  84. }
  85. return fmt.Errorf("lookup bucket %s/%s: %v", s3a.option.BucketsPath, bucket, err)
  86. }
  87. return nil
  88. })
  89. if err != nil {
  90. writeErrorResponse(w, ErrNoSuchBucket, r.URL)
  91. return
  92. }
  93. writeSuccessResponseEmpty(w)
  94. }