diff options
24 files changed, 2590 insertions, 149 deletions
diff --git a/weed/command/command.go b/weed/command/command.go index c451936e5..c6b005dd9 100644 --- a/weed/command/command.go +++ b/weed/command/command.go @@ -16,6 +16,7 @@ var Commands = []*Command{ cmdServer, cmdMaster, cmdFiler, + cmdS3, cmdUpload, cmdDownload, cmdShell, diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go index 4905df986..fda15090f 100644 --- a/weed/command/mount_std.go +++ b/weed/command/mount_std.go @@ -53,27 +53,14 @@ func runMount(cmd *Command, args []string) bool { c.Close() }) - hostnameAndPort := strings.Split(*mountOptions.filer, ":") - if len(hostnameAndPort) != 2 { - fmt.Printf("The filer should have hostname:port format: %v\n", hostnameAndPort) - return false - } - - filerPort, parseErr := strconv.ParseUint(hostnameAndPort[1], 10, 64) - if parseErr != nil { - fmt.Printf("The filer filer port parse error: %v\n", parseErr) + filerGrpcAddress, err := parseFilerGrpcAddress(*mountOptions.filer, *mountOptions.filerGrpcPort) + if err != nil { + glog.Fatal(err) return false } - filerGrpcPort := filerPort + 10000 - if *mountOptions.filerGrpcPort != 0 { - filerGrpcPort = uint64(*copy.filerGrpcPort) - } - - filerAddress := fmt.Sprintf("%s:%d", hostnameAndPort[0], filerGrpcPort) - err = fs.Serve(c, filesys.NewSeaweedFileSystem( - filerAddress, *mountOptions.filerMountRootPath, *mountOptions.collection, *mountOptions.replication, int32(*mountOptions.ttlSec), + filerGrpcAddress, *mountOptions.filerMountRootPath, *mountOptions.collection, *mountOptions.replication, int32(*mountOptions.ttlSec), *mountOptions.chunkSizeLimitMB, *mountOptions.dataCenter)) if err != nil { fuse.Unmount(*mountOptions.dir) @@ -87,3 +74,22 @@ func runMount(cmd *Command, args []string) bool { return true } + +func parseFilerGrpcAddress(filer string, optionalGrpcPort int) (filerGrpcAddress string, err error) { + hostnameAndPort := strings.Split(filer, ":") + if len(hostnameAndPort) != 2 { + return "", fmt.Errorf("The filer should have hostname:port format: %v", hostnameAndPort) + } + + filerPort, parseErr := strconv.ParseUint(hostnameAndPort[1], 10, 64) + if parseErr != nil { + return "", fmt.Errorf("The filer filer port parse error: %v", parseErr) + } + + filerGrpcPort := int(filerPort) + 10000 + if optionalGrpcPort != 0 { + filerGrpcPort = optionalGrpcPort + } + + return fmt.Sprintf("%s:%d", hostnameAndPort[0], filerGrpcPort), nil +} diff --git a/weed/command/s3.go b/weed/command/s3.go new file mode 100644 index 000000000..03fa80ed8 --- /dev/null +++ b/weed/command/s3.go @@ -0,0 +1,76 @@ +package command + +import ( + "net/http" + "time" + + "github.com/chrislusf/seaweedfs/weed/glog" + "github.com/chrislusf/seaweedfs/weed/util" + "github.com/gorilla/mux" + "fmt" + "github.com/chrislusf/seaweedfs/weed/s3api" +) + +var ( + s3options S3Options +) + +type S3Options struct { + filer *string + filerGrpcPort *int + filerBucketsPath *string + port *int + domainName *string +} + +func init() { + cmdS3.Run = runS3 // break init cycle + s3options.filer = cmdS3.Flag.String("filer", "localhost:8888", "filer server address") + s3options.filerGrpcPort = cmdS3.Flag.Int("filer.grpcPort", 0, "filer server grpc port, default to filer http port plus 10000") + s3options.filerBucketsPath = cmdS3.Flag.String("filer.dir.buckets", "/s3buckets", "folder on filer to store all buckets") + s3options.port = cmdS3.Flag.Int("port", 8333, "s3options server http listen port") + s3options.domainName = cmdS3.Flag.String("domainName", "", "suffix of the host name, {bucket}.{domainName}") +} + +var cmdS3 = &Command{ + UsageLine: "s3 -port=8333 -filer=<ip:port>", + Short: "start a s3 API compatible server that is backed by a filer", + Long: `start a s3 API compatible server that is backed by a filer. + +`, +} + +func runS3(cmd *Command, args []string) bool { + + filerGrpcAddress, err := parseFilerGrpcAddress(*s3options.filer, *s3options.filerGrpcPort) + if err != nil { + glog.Fatal(err) + return false + } + + router := mux.NewRouter().SkipClean(true) + + _, s3ApiServer_err := s3api.NewS3ApiServer(router, &s3api.S3ApiServerOption{ + Filer: *s3options.filer, + FilerGrpcAddress: filerGrpcAddress, + DomainName: *s3options.domainName, + BucketsPath: *s3options.filerBucketsPath, + }) + if s3ApiServer_err != nil { + glog.Fatalf("S3 API Server startup error: %v", s3ApiServer_err) + } + + glog.V(0).Infof("Start Seaweed S3 API Server %s at port %d", util.VERSION, *s3options.port) + s3ApiListener, e := util.NewListener(fmt.Sprintf(":%d", *s3options.port), time.Duration(10)*time.Second) + if e != nil { + glog.Fatalf("S3 API Server listener error: %v", e) + } + + httpS := &http.Server{Handler: router} + if err := httpS.Serve(s3ApiListener); err != nil { + glog.Fatalf("S3 API Server Fail to serve: %v", e) + } + + return true + +} diff --git a/weed/filer2/abstract_sql/abstract_sql_store.go b/weed/filer2/abstract_sql/abstract_sql_store.go index 82ef571b6..d6bb717ca 100644 --- a/weed/filer2/abstract_sql/abstract_sql_store.go +++ b/weed/filer2/abstract_sql/abstract_sql_store.go @@ -64,7 +64,7 @@ func (store *AbstractSqlStore) FindEntry(fullpath filer2.FullPath) (*filer2.Entr row := store.DB.QueryRow(store.SqlFind, hashToLong(dir), name, dir) var data []byte if err := row.Scan(&data); err != nil { - return nil, fmt.Errorf("read entry %s: %v", fullpath, err) + return nil, filer2.ErrNotFound } entry := &filer2.Entry{ diff --git a/weed/filer2/cassandra/cassandra_store.go b/weed/filer2/cassandra/cassandra_store.go index d731cd99c..7552cb524 100644 --- a/weed/filer2/cassandra/cassandra_store.go +++ b/weed/filer2/cassandra/cassandra_store.go @@ -68,7 +68,7 @@ func (store *CassandraStore) FindEntry(fullpath filer2.FullPath) (entry *filer2. "SELECT meta FROM filemeta WHERE directory=? AND name=?", dir, name).Consistency(gocql.One).Scan(&data); err != nil { if err != gocql.ErrNotFound { - return nil, fmt.Errorf("read entry %s: %v", fullpath, err) + return nil, filer2.ErrNotFound } } diff --git a/weed/filer2/filer.go b/weed/filer2/filer.go index a98194bc8..2ecf3976e 100644 --- a/weed/filer2/filer.go +++ b/weed/filer2/filer.go @@ -125,7 +125,7 @@ func (f *Filer) FindEntry(p FullPath) (entry *Entry, err error) { return f.store.FindEntry(p) } -func (f *Filer) DeleteEntryMetaAndData(p FullPath, shouldDeleteChunks bool) (err error) { +func (f *Filer) DeleteEntryMetaAndData(p FullPath, isRecursive bool, shouldDeleteChunks bool) (err error) { entry, err := f.FindEntry(p) if err != nil { return err @@ -136,8 +136,14 @@ func (f *Filer) DeleteEntryMetaAndData(p FullPath, shouldDeleteChunks bool) (err if err != nil { return fmt.Errorf("list folder %s: %v", p, err) } - if len(entries) > 0 { - return fmt.Errorf("folder %s is not empty", p) + if isRecursive { + for _, sub := range entries { + f.DeleteEntryMetaAndData(sub.FullPath, isRecursive, shouldDeleteChunks) + } + } else { + if len(entries) > 0 { + return fmt.Errorf("folder %s is not empty", p) + } } f.cacheDelDirectory(string(p)) } @@ -158,7 +164,7 @@ func (f *Filer) ListDirectoryEntries(p FullPath, startFileName string, inclusive func (f *Filer) cacheDelDirectory(dirpath string) { if f.directoryCache == nil { - return + return } f.directoryCache.Delete(dirpath) return diff --git a/weed/filer2/filerstore.go b/weed/filer2/filerstore.go index b169c6f80..68fc06a5d 100644 --- a/weed/filer2/filerstore.go +++ b/weed/filer2/filerstore.go @@ -11,6 +11,7 @@ type FilerStore interface { Initialize(configuration Configuration) error InsertEntry(*Entry) error UpdateEntry(*Entry) (err error) + // err == filer2.ErrNotFound if not found FindEntry(FullPath) (entry *Entry, err error) DeleteEntry(FullPath) (err error) ListDirectoryEntries(dirPath FullPath, startFileName string, includeStartFile bool, limit int) ([]*Entry, error) diff --git a/weed/filer2/memdb/memdb_store.go b/weed/filer2/memdb/memdb_store.go index 48a9bea31..08cee0afd 100644 --- a/weed/filer2/memdb/memdb_store.go +++ b/weed/filer2/memdb/memdb_store.go @@ -49,7 +49,7 @@ func (store *MemDbStore) UpdateEntry(entry *filer2.Entry) (err error) { func (store *MemDbStore) FindEntry(fullpath filer2.FullPath) (entry *filer2.Entry, err error) { item := store.tree.Get(entryItem{&filer2.Entry{FullPath: fullpath}}) if item == nil { - return nil, nil + return nil, filer2.ErrNotFound } entry = item.(entryItem).Entry return entry, nil diff --git a/weed/filer2/memdb/memdb_store_test.go b/weed/filer2/memdb/memdb_store_test.go index 84ee06ce1..cf813e04b 100644 --- a/weed/filer2/memdb/memdb_store_test.go +++ b/weed/filer2/memdb/memdb_store_test.go @@ -134,7 +134,7 @@ func TestCreateFileAndList(t *testing.T) { } // delete file and count - filer.DeleteEntryMetaAndData(file3Path, false) + filer.DeleteEntryMetaAndData(file3Path, false, false) entries, _ = filer.ListDirectoryEntries(filer2.FullPath("/home/chris/this/is"), "", false, 100) if len(entries) != 1 { t.Errorf("list entries count: %v", len(entries)) diff --git a/weed/operation/assign_file_id.go b/weed/operation/assign_file_id.go index c2e1e4444..169fd664d 100644 --- a/weed/operation/assign_file_id.go +++ b/weed/operation/assign_file_id.go @@ -59,8 +59,9 @@ func Assign(server string, primaryRequest *VolumeAssignRequest, alternativeReque values.Add("dataNode", request.DataNode) } - jsonBlob, err := util.Post("http://"+server+"/dir/assign", values) - glog.V(2).Infof("assign result from %s : %s", server, string(jsonBlob)) + postUrl := fmt.Sprintf("http://%s/dir/assign", server) + jsonBlob, err := util.Post(postUrl, values) + glog.V(2).Infof("assign %d result from %s %+v : %s", i, postUrl, values, string(jsonBlob)) if err != nil { return nil, err } diff --git a/weed/pb/filer.proto b/weed/pb/filer.proto index fe1fe4d8d..a01ee7a2e 100644 --- a/weed/pb/filer.proto +++ b/weed/pb/filer.proto @@ -30,6 +30,9 @@ service SeaweedFiler { rpc LookupVolume (LookupVolumeRequest) returns (LookupVolumeResponse) { } + rpc DeleteCollection (DeleteCollectionRequest) returns (DeleteCollectionResponse) { + } + } ////////////////////////////////////////////////// @@ -117,6 +120,7 @@ message DeleteEntryRequest { string name = 2; bool is_directory = 3; bool is_delete_data = 4; + bool is_recursive = 5; } message DeleteEntryResponse { @@ -152,3 +156,10 @@ message Location { message LookupVolumeResponse { map<string, Locations> locations_map = 1; } + +message DeleteCollectionRequest { + string collection = 1; +} + +message DeleteCollectionResponse { +} diff --git a/weed/pb/filer_pb/filer.pb.go b/weed/pb/filer_pb/filer.pb.go index 0756c6c7c..d7f279a17 100644 --- a/weed/pb/filer_pb/filer.pb.go +++ b/weed/pb/filer_pb/filer.pb.go @@ -32,6 +32,8 @@ It has these top-level messages: Locations Location LookupVolumeResponse + DeleteCollectionRequest + DeleteCollectionResponse */ package filer_pb @@ -452,6 +454,7 @@ type DeleteEntryRequest struct { Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` IsDirectory bool `protobuf:"varint,3,opt,name=is_directory,json=isDirectory" json:"is_directory,omitempty"` IsDeleteData bool `protobuf:"varint,4,opt,name=is_delete_data,json=isDeleteData" json:"is_delete_data,omitempty"` + IsRecursive bool `protobuf:"varint,5,opt,name=is_recursive,json=isRecursive" json:"is_recursive,omitempty"` } func (m *DeleteEntryRequest) Reset() { *m = DeleteEntryRequest{} } @@ -487,6 +490,13 @@ func (m *DeleteEntryRequest) GetIsDeleteData() bool { return false } +func (m *DeleteEntryRequest) GetIsRecursive() bool { + if m != nil { + return m.IsRecursive + } + return false +} + type DeleteEntryResponse struct { } @@ -655,6 +665,30 @@ func (m *LookupVolumeResponse) GetLocationsMap() map[string]*Locations { return nil } +type DeleteCollectionRequest struct { + Collection string `protobuf:"bytes,1,opt,name=collection" json:"collection,omitempty"` +} + +func (m *DeleteCollectionRequest) Reset() { *m = DeleteCollectionRequest{} } +func (m *DeleteCollectionRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteCollectionRequest) ProtoMessage() {} +func (*DeleteCollectionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } + +func (m *DeleteCollectionRequest) GetCollection() string { + if m != nil { + return m.Collection + } + return "" +} + +type DeleteCollectionResponse struct { +} + +func (m *DeleteCollectionResponse) Reset() { *m = DeleteCollectionResponse{} } +func (m *DeleteCollectionResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteCollectionResponse) ProtoMessage() {} +func (*DeleteCollectionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } + func init() { proto.RegisterType((*LookupDirectoryEntryRequest)(nil), "filer_pb.LookupDirectoryEntryRequest") proto.RegisterType((*LookupDirectoryEntryResponse)(nil), "filer_pb.LookupDirectoryEntryResponse") @@ -679,6 +713,8 @@ func init() { proto.RegisterType((*Locations)(nil), "filer_pb.Locations") proto.RegisterType((*Location)(nil), "filer_pb.Location") proto.RegisterType((*LookupVolumeResponse)(nil), "filer_pb.LookupVolumeResponse") + proto.RegisterType((*DeleteCollectionRequest)(nil), "filer_pb.DeleteCollectionRequest") + proto.RegisterType((*DeleteCollectionResponse)(nil), "filer_pb.DeleteCollectionResponse") } // Reference imports to suppress errors if they are not otherwise used. @@ -700,6 +736,7 @@ type SeaweedFilerClient interface { DeleteEntry(ctx context.Context, in *DeleteEntryRequest, opts ...grpc.CallOption) (*DeleteEntryResponse, error) AssignVolume(ctx context.Context, in *AssignVolumeRequest, opts ...grpc.CallOption) (*AssignVolumeResponse, error) LookupVolume(ctx context.Context, in *LookupVolumeRequest, opts ...grpc.CallOption) (*LookupVolumeResponse, error) + DeleteCollection(ctx context.Context, in *DeleteCollectionRequest, opts ...grpc.CallOption) (*DeleteCollectionResponse, error) } type seaweedFilerClient struct { @@ -782,6 +819,15 @@ func (c *seaweedFilerClient) LookupVolume(ctx context.Context, in *LookupVolumeR return out, nil } +func (c *seaweedFilerClient) DeleteCollection(ctx context.Context, in *DeleteCollectionRequest, opts ...grpc.CallOption) (*DeleteCollectionResponse, error) { + out := new(DeleteCollectionResponse) + err := grpc.Invoke(ctx, "/filer_pb.SeaweedFiler/DeleteCollection", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for SeaweedFiler service type SeaweedFilerServer interface { @@ -793,6 +839,7 @@ type SeaweedFilerServer interface { DeleteEntry(context.Context, *DeleteEntryRequest) (*DeleteEntryResponse, error) AssignVolume(context.Context, *AssignVolumeRequest) (*AssignVolumeResponse, error) LookupVolume(context.Context, *LookupVolumeRequest) (*LookupVolumeResponse, error) + DeleteCollection(context.Context, *DeleteCollectionRequest) (*DeleteCollectionResponse, error) } func RegisterSeaweedFilerServer(s *grpc.Server, srv SeaweedFilerServer) { @@ -943,6 +990,24 @@ func _SeaweedFiler_LookupVolume_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _SeaweedFiler_DeleteCollection_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteCollectionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SeaweedFilerServer).DeleteCollection(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/filer_pb.SeaweedFiler/DeleteCollection", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SeaweedFilerServer).DeleteCollection(ctx, req.(*DeleteCollectionRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _SeaweedFiler_serviceDesc = grpc.ServiceDesc{ ServiceName: "filer_pb.SeaweedFiler", HandlerType: (*SeaweedFilerServer)(nil), @@ -979,6 +1044,10 @@ var _SeaweedFiler_serviceDesc = grpc.ServiceDesc{ MethodName: "LookupVolume", Handler: _SeaweedFiler_LookupVolume_Handler, }, + { + MethodName: "DeleteCollection", + Handler: _SeaweedFiler_DeleteCollection_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "filer.proto", @@ -987,67 +1056,71 @@ var _SeaweedFiler_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("filer.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 990 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xdc, 0x44, - 0x14, 0x8e, 0xd7, 0xbb, 0x9b, 0xf5, 0xd9, 0x4d, 0x81, 0xd9, 0xb4, 0x98, 0x6d, 0x52, 0x96, 0xa1, - 0x45, 0xa9, 0x90, 0xa2, 0x28, 0x70, 0x51, 0x81, 0x90, 0xa8, 0x92, 0x52, 0x55, 0x4a, 0x55, 0xc9, - 0x21, 0x48, 0x5c, 0xad, 0x1c, 0xfb, 0x64, 0x19, 0xc5, 0x6b, 0x2f, 0x9e, 0x71, 0x50, 0xb8, 0xe5, - 0x92, 0x0b, 0x9e, 0x02, 0xf1, 0x02, 0xbc, 0x01, 0x2f, 0x86, 0xe6, 0xc7, 0xde, 0xf1, 0xda, 0xdb, - 0x9f, 0x8b, 0xde, 0xcd, 0x9c, 0x9f, 0xef, 0x7c, 0xc7, 0x3e, 0xe7, 0xb3, 0x61, 0x78, 0xc5, 0x12, - 0xcc, 0x0f, 0x97, 0x79, 0x26, 0x32, 0x32, 0x50, 0x97, 0xd9, 0xf2, 0x92, 0xbe, 0x82, 0xfb, 0x67, - 0x59, 0x76, 0x5d, 0x2c, 0x4f, 0x59, 0x8e, 0x91, 0xc8, 0xf2, 0xdb, 0x67, 0xa9, 0xc8, 0x6f, 0x03, - 0xfc, 0xb5, 0x40, 0x2e, 0xc8, 0x1e, 0x78, 0x71, 0xe9, 0xf0, 0x9d, 0xa9, 0x73, 0xe0, 0x05, 0x2b, - 0x03, 0x21, 0xd0, 0x4d, 0xc3, 0x05, 0xfa, 0x1d, 0xe5, 0x50, 0x67, 0xfa, 0x0c, 0xf6, 0xda, 0x01, - 0xf9, 0x32, 0x4b, 0x39, 0x92, 0x47, 0xd0, 0x43, 0x69, 0x50, 0x68, 0xc3, 0xe3, 0x0f, 0x0e, 0x4b, - 0x2a, 0x87, 0x3a, 0x4e, 0x7b, 0xe9, 0x31, 0x90, 0x33, 0xc6, 0x85, 0xb4, 0x31, 0xe4, 0x6f, 0x45, - 0x87, 0x7e, 0x0f, 0xe3, 0x5a, 0x8e, 0xa9, 0xf8, 0x18, 0xb6, 0x51, 0x9b, 0x7c, 0x67, 0xea, 0xb6, - 0xd5, 0x2c, 0xfd, 0xf4, 0x6f, 0x07, 0x7a, 0xca, 0x54, 0xb5, 0xe6, 0xac, 0x5a, 0x23, 0x9f, 0xc1, - 0x88, 0xf1, 0xd9, 0x8a, 0x80, 0x6c, 0x7b, 0x10, 0x0c, 0x19, 0xaf, 0x5a, 0x25, 0x5f, 0x42, 0x3f, - 0xfa, 0xa5, 0x48, 0xaf, 0xb9, 0xef, 0xaa, 0x52, 0xe3, 0x55, 0xa9, 0x1f, 0x58, 0x82, 0x27, 0xd2, - 0x17, 0x98, 0x10, 0xf2, 0x04, 0x20, 0x14, 0x22, 0x67, 0x97, 0x85, 0x40, 0xee, 0x77, 0xd5, 0xf3, - 0xf0, 0xad, 0x84, 0x82, 0xe3, 0xd3, 0xca, 0x1f, 0x58, 0xb1, 0xf4, 0x0a, 0xbc, 0x0a, 0x8e, 0x7c, - 0x0c, 0xdb, 0x32, 0x67, 0xc6, 0x62, 0xc3, 0xb6, 0x2f, 0xaf, 0x2f, 0x62, 0x72, 0x0f, 0xfa, 0xd9, - 0xd5, 0x15, 0x47, 0xa1, 0x98, 0xba, 0x81, 0xb9, 0xc9, 0xde, 0x38, 0xfb, 0x1d, 0x7d, 0x77, 0xea, - 0x1c, 0x74, 0x03, 0x75, 0x26, 0xbb, 0xd0, 0x5b, 0x08, 0xb6, 0x40, 0x45, 0xc3, 0x0d, 0xf4, 0x85, - 0xfe, 0xd9, 0x81, 0x3b, 0x75, 0x1a, 0xe4, 0x3e, 0x78, 0xaa, 0x9a, 0x42, 0x70, 0x14, 0x82, 0x9a, - 0xa6, 0xf3, 0x1a, 0x4a, 0xc7, 0x42, 0xa9, 0x52, 0x16, 0x59, 0xac, 0x8b, 0xee, 0xe8, 0x94, 0x97, - 0x59, 0x8c, 0xe4, 0x43, 0x70, 0x0b, 0x16, 0xab, 0xb2, 0x3b, 0x81, 0x3c, 0x4a, 0xcb, 0x9c, 0xc5, - 0x7e, 0x4f, 0x5b, 0xe6, 0x4c, 0x35, 0x12, 0xe5, 0x0a, 0xb7, 0xaf, 0x1b, 0xd1, 0x37, 0xd9, 0xc8, - 0x42, 0x5a, 0xb7, 0xf5, 0x4b, 0x92, 0x67, 0x32, 0x85, 0x61, 0x8e, 0xcb, 0x84, 0x45, 0xa1, 0x60, - 0x59, 0xea, 0x0f, 0x94, 0xcb, 0x36, 0x91, 0x07, 0x00, 0x51, 0x96, 0x24, 0x18, 0xa9, 0x00, 0x4f, - 0x05, 0x58, 0x16, 0xf9, 0x3c, 0x85, 0x48, 0x66, 0x1c, 0x23, 0x1f, 0xa6, 0xce, 0x41, 0x2f, 0xe8, - 0x0b, 0x91, 0x9c, 0x63, 0x44, 0xe7, 0xf0, 0xc9, 0x73, 0x54, 0xe3, 0x75, 0x6b, 0xbd, 0x17, 0x33, - 0x9a, 0x6d, 0x03, 0xb3, 0x0f, 0xb0, 0x0c, 0x73, 0x4c, 0x85, 0x1c, 0x1a, 0xb3, 0x25, 0x9e, 0xb6, - 0x9c, 0xb2, 0xdc, 0x7e, 0x71, 0xae, 0xfd, 0xe2, 0xe8, 0x1f, 0x0e, 0x4c, 0xda, 0x2a, 0x99, 0x81, - 0xae, 0xcf, 0x8d, 0xf3, 0xf6, 0x73, 0x63, 0x8d, 0x67, 0xe7, 0x8d, 0xe3, 0x49, 0x8f, 0xe0, 0xee, - 0x73, 0x14, 0xca, 0x9e, 0xa5, 0x02, 0x53, 0x51, 0xb6, 0xba, 0x69, 0xe0, 0xe8, 0x31, 0xdc, 0x5b, - 0xcf, 0x30, 0x94, 0x7d, 0xd8, 0x8e, 0xb4, 0x49, 0xa5, 0x8c, 0x82, 0xf2, 0x4a, 0x7f, 0x06, 0x72, - 0x92, 0x63, 0x28, 0xf0, 0x1d, 0x74, 0xa7, 0xd2, 0x90, 0xce, 0x6b, 0x35, 0xe4, 0x2e, 0x8c, 0x6b, - 0xd0, 0x9a, 0x8b, 0xac, 0x78, 0xb1, 0x8c, 0xdf, 0x57, 0xc5, 0x1a, 0xb4, 0xa9, 0xf8, 0x97, 0x03, - 0xe4, 0x14, 0x13, 0x7c, 0xa7, 0x92, 0x2d, 0xe2, 0xda, 0x50, 0x20, 0xb7, 0xa9, 0x40, 0x0f, 0xe1, - 0x8e, 0x0c, 0x51, 0xd5, 0x66, 0x71, 0x28, 0x42, 0xb5, 0x5a, 0x83, 0x60, 0xc4, 0xb8, 0xa6, 0x70, - 0x1a, 0x8a, 0x50, 0x12, 0xad, 0x11, 0x32, 0x44, 0xff, 0x71, 0x60, 0xfc, 0x94, 0x73, 0x36, 0x4f, - 0x7f, 0xca, 0x92, 0x62, 0x81, 0x25, 0xd3, 0x5d, 0xe8, 0x45, 0x59, 0x61, 0x5e, 0x5e, 0x2f, 0xd0, - 0x97, 0xb5, 0x45, 0xea, 0x34, 0x16, 0x69, 0x6d, 0x15, 0xdd, 0xe6, 0x2a, 0x5a, 0xab, 0xd6, 0xb5, - 0x57, 0x8d, 0x7c, 0x0a, 0x43, 0xc9, 0x7d, 0x16, 0x61, 0x2a, 0x30, 0x57, 0x5a, 0xe0, 0x05, 0x20, - 0x4d, 0x27, 0xca, 0x42, 0x6f, 0x60, 0xb7, 0x4e, 0xd4, 0x0c, 0xda, 0x46, 0x31, 0x94, 0x3a, 0x93, - 0x27, 0x86, 0xa5, 0x3c, 0xaa, 0xed, 0x2c, 0x2e, 0x13, 0x16, 0xcd, 0xa4, 0xc3, 0x35, 0xdb, 0xa9, - 0x2c, 0x17, 0x79, 0xb2, 0xea, 0xb9, 0x6b, 0xf5, 0x4c, 0xbf, 0x86, 0xb1, 0xfe, 0xbc, 0xd5, 0x1f, - 0xd0, 0x3e, 0xc0, 0x8d, 0x32, 0xcc, 0x58, 0xac, 0x3f, 0x33, 0x5e, 0xe0, 0x69, 0xcb, 0x8b, 0x98, - 0xd3, 0xef, 0xc0, 0x3b, 0xcb, 0x74, 0xcf, 0x9c, 0x1c, 0x81, 0x97, 0x94, 0x17, 0xf3, 0x45, 0x22, - 0xab, 0x79, 0x2a, 0xe3, 0x82, 0x55, 0x10, 0xfd, 0x16, 0x06, 0xa5, 0xb9, 0xec, 0xc3, 0xd9, 0xd4, - 0x47, 0x67, 0xad, 0x0f, 0xfa, 0x9f, 0x03, 0xbb, 0x75, 0xca, 0xe6, 0x51, 0x5d, 0xc0, 0x4e, 0x55, - 0x62, 0xb6, 0x08, 0x97, 0x86, 0xcb, 0x91, 0xcd, 0xa5, 0x99, 0x56, 0x11, 0xe4, 0x2f, 0xc3, 0xa5, - 0x9e, 0x9e, 0x51, 0x62, 0x99, 0x26, 0x3f, 0xc2, 0x47, 0x8d, 0x10, 0xc9, 0xfa, 0x1a, 0xcb, 0x21, - 0x97, 0x47, 0xf2, 0x18, 0x7a, 0x37, 0x61, 0x52, 0xa0, 0xd9, 0xa8, 0x71, 0xf3, 0x09, 0xf0, 0x40, - 0x47, 0x7c, 0xd3, 0x79, 0xe2, 0x1c, 0xff, 0xdb, 0x83, 0xd1, 0x39, 0x86, 0xbf, 0x21, 0xc6, 0x52, - 0x5f, 0x72, 0x32, 0x2f, 0xbb, 0xaa, 0xff, 0x67, 0x90, 0x47, 0xeb, 0xf4, 0x5b, 0x7f, 0x6c, 0x26, - 0x5f, 0xbc, 0x29, 0xcc, 0x6c, 0xc4, 0x16, 0x39, 0x83, 0xa1, 0xf5, 0x57, 0x41, 0xf6, 0xac, 0xc4, - 0xc6, 0x0f, 0xca, 0x64, 0x7f, 0x83, 0xb7, 0x42, 0x0b, 0x81, 0x34, 0x95, 0x9d, 0x7c, 0xbe, 0x4a, - 0xdb, 0xf8, 0x85, 0x99, 0x3c, 0x7c, 0x7d, 0x90, 0x4d, 0xd8, 0x92, 0x3d, 0x9b, 0x70, 0x53, 0x68, - 0x6d, 0xc2, 0x6d, 0x5a, 0xa9, 0xd0, 0x2c, 0x49, 0xb3, 0xd1, 0x9a, 0x22, 0x6a, 0xa3, 0xb5, 0xe9, - 0xa0, 0x42, 0xb3, 0x74, 0xc7, 0x46, 0x6b, 0xea, 0xa3, 0x8d, 0xd6, 0x26, 0x56, 0x5b, 0xe4, 0x15, - 0x8c, 0x6c, 0x11, 0x20, 0x56, 0x42, 0x8b, 0x8a, 0x4d, 0x1e, 0x6c, 0x72, 0xdb, 0x80, 0xf6, 0xcc, - 0xdb, 0x80, 0x2d, 0x5b, 0x6f, 0x03, 0xb6, 0xad, 0x0a, 0xdd, 0xba, 0xec, 0xab, 0xff, 0xed, 0xaf, - 0xfe, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x65, 0x12, 0xc7, 0x9d, 0x7e, 0x0b, 0x00, 0x00, + // 1049 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x57, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x0e, 0x45, 0x4b, 0x16, 0x47, 0x72, 0x9a, 0xae, 0x9c, 0x84, 0x55, 0xec, 0x54, 0xd9, 0x26, + 0x85, 0x83, 0x02, 0x86, 0xe1, 0xf6, 0x90, 0xb6, 0x28, 0xd0, 0xc0, 0x4e, 0x83, 0x00, 0x0e, 0x02, + 0xd0, 0x75, 0x81, 0xa2, 0x07, 0x81, 0x26, 0xc7, 0xea, 0xc2, 0x14, 0xa9, 0x72, 0x97, 0x2e, 0xdc, + 0x6b, 0x8f, 0x3d, 0xf5, 0x21, 0x8a, 0xde, 0xfb, 0x0a, 0x7d, 0xb1, 0x62, 0x7f, 0x48, 0x2d, 0x45, + 0xca, 0x49, 0x0e, 0xbd, 0xed, 0xce, 0xce, 0x7c, 0x33, 0xdf, 0x72, 0xe6, 0x5b, 0x09, 0x06, 0x17, + 0x2c, 0xc1, 0x7c, 0x7f, 0x91, 0x67, 0x22, 0x23, 0x7d, 0xb5, 0x99, 0x2e, 0xce, 0xe9, 0x1b, 0x78, + 0x70, 0x92, 0x65, 0x97, 0xc5, 0xe2, 0x98, 0xe5, 0x18, 0x89, 0x2c, 0xbf, 0x7e, 0x91, 0x8a, 0xfc, + 0x3a, 0xc0, 0x5f, 0x0a, 0xe4, 0x82, 0xec, 0x80, 0x17, 0x97, 0x07, 0xbe, 0x33, 0x71, 0xf6, 0xbc, + 0x60, 0x69, 0x20, 0x04, 0x36, 0xd2, 0x70, 0x8e, 0x7e, 0x47, 0x1d, 0xa8, 0x35, 0x7d, 0x01, 0x3b, + 0xed, 0x80, 0x7c, 0x91, 0xa5, 0x1c, 0xc9, 0x13, 0xe8, 0xa2, 0x34, 0x28, 0xb4, 0xc1, 0xe1, 0x07, + 0xfb, 0x65, 0x29, 0xfb, 0xda, 0x4f, 0x9f, 0xd2, 0x43, 0x20, 0x27, 0x8c, 0x0b, 0x69, 0x63, 0xc8, + 0xdf, 0xa9, 0x1c, 0xfa, 0x2d, 0x8c, 0x6a, 0x31, 0x26, 0xe3, 0x53, 0xd8, 0x44, 0x6d, 0xf2, 0x9d, + 0x89, 0xdb, 0x96, 0xb3, 0x3c, 0xa7, 0x7f, 0x39, 0xd0, 0x55, 0xa6, 0x8a, 0x9a, 0xb3, 0xa4, 0x46, + 0x1e, 0xc1, 0x90, 0xf1, 0xe9, 0xb2, 0x00, 0x49, 0xbb, 0x1f, 0x0c, 0x18, 0xaf, 0xa8, 0x92, 0xcf, + 0xa0, 0x17, 0xfd, 0x5c, 0xa4, 0x97, 0xdc, 0x77, 0x55, 0xaa, 0xd1, 0x32, 0xd5, 0x77, 0x2c, 0xc1, + 0x23, 0x79, 0x16, 0x18, 0x17, 0xf2, 0x0c, 0x20, 0x14, 0x22, 0x67, 0xe7, 0x85, 0x40, 0xee, 0x6f, + 0xa8, 0xfb, 0xf0, 0xad, 0x80, 0x82, 0xe3, 0xf3, 0xea, 0x3c, 0xb0, 0x7c, 0xe9, 0x05, 0x78, 0x15, + 0x1c, 0xb9, 0x0f, 0x9b, 0x32, 0x66, 0xca, 0x62, 0x53, 0x6d, 0x4f, 0x6e, 0x5f, 0xc5, 0xe4, 0x1e, + 0xf4, 0xb2, 0x8b, 0x0b, 0x8e, 0x42, 0x55, 0xea, 0x06, 0x66, 0x27, 0xb9, 0x71, 0xf6, 0x1b, 0xfa, + 0xee, 0xc4, 0xd9, 0xdb, 0x08, 0xd4, 0x9a, 0x6c, 0x43, 0x77, 0x2e, 0xd8, 0x1c, 0x55, 0x19, 0x6e, + 0xa0, 0x37, 0xf4, 0x8f, 0x0e, 0xdc, 0xae, 0x97, 0x41, 0x1e, 0x80, 0xa7, 0xb2, 0x29, 0x04, 0x47, + 0x21, 0xa8, 0x6e, 0x3a, 0xad, 0xa1, 0x74, 0x2c, 0x94, 0x2a, 0x64, 0x9e, 0xc5, 0x3a, 0xe9, 0x96, + 0x0e, 0x79, 0x9d, 0xc5, 0x48, 0xee, 0x80, 0x5b, 0xb0, 0x58, 0xa5, 0xdd, 0x0a, 0xe4, 0x52, 0x5a, + 0x66, 0x2c, 0xf6, 0xbb, 0xda, 0x32, 0x63, 0x8a, 0x48, 0x94, 0x2b, 0xdc, 0x9e, 0x26, 0xa2, 0x77, + 0x92, 0xc8, 0x5c, 0x5a, 0x37, 0xf5, 0x47, 0x92, 0x6b, 0x32, 0x81, 0x41, 0x8e, 0x8b, 0x84, 0x45, + 0xa1, 0x60, 0x59, 0xea, 0xf7, 0xd5, 0x91, 0x6d, 0x22, 0x0f, 0x01, 0xa2, 0x2c, 0x49, 0x30, 0x52, + 0x0e, 0x9e, 0x72, 0xb0, 0x2c, 0xf2, 0x3e, 0x85, 0x48, 0xa6, 0x1c, 0x23, 0x1f, 0x26, 0xce, 0x5e, + 0x37, 0xe8, 0x09, 0x91, 0x9c, 0x62, 0x44, 0x67, 0xf0, 0xd1, 0x4b, 0x54, 0xed, 0x75, 0x6d, 0x7d, + 0x17, 0xd3, 0x9a, 0x6d, 0x0d, 0xb3, 0x0b, 0xb0, 0x08, 0x73, 0x4c, 0x85, 0x6c, 0x1a, 0x33, 0x25, + 0x9e, 0xb6, 0x1c, 0xb3, 0xdc, 0xfe, 0x70, 0xae, 0xfd, 0xe1, 0xe8, 0xef, 0x0e, 0x8c, 0xdb, 0x32, + 0x99, 0x86, 0xae, 0xf7, 0x8d, 0xf3, 0xee, 0x7d, 0x63, 0xb5, 0x67, 0xe7, 0xad, 0xed, 0x49, 0x0f, + 0xe0, 0xee, 0x4b, 0x14, 0xca, 0x9e, 0xa5, 0x02, 0x53, 0x51, 0x52, 0x5d, 0xd7, 0x70, 0xf4, 0x10, + 0xee, 0xad, 0x46, 0x98, 0x92, 0x7d, 0xd8, 0x8c, 0xb4, 0x49, 0x85, 0x0c, 0x83, 0x72, 0x4b, 0x7f, + 0x04, 0x72, 0x94, 0x63, 0x28, 0xf0, 0x3d, 0x74, 0xa7, 0xd2, 0x90, 0xce, 0x8d, 0x1a, 0x72, 0x17, + 0x46, 0x35, 0x68, 0x5d, 0x8b, 0xcc, 0x78, 0xb6, 0x88, 0xff, 0xaf, 0x8c, 0x35, 0x68, 0x93, 0xf1, + 0x1f, 0x07, 0xc8, 0x31, 0x26, 0xf8, 0x5e, 0x29, 0x5b, 0xc4, 0xb5, 0xa1, 0x40, 0x6e, 0x53, 0x81, + 0x1e, 0xc3, 0x6d, 0xe9, 0xa2, 0xb2, 0x4d, 0xe3, 0x50, 0x84, 0x6a, 0xb4, 0xfa, 0xc1, 0x90, 0x71, + 0x5d, 0xc2, 0x71, 0x28, 0x42, 0x03, 0x94, 0x63, 0x54, 0xe4, 0x9c, 0x5d, 0xa1, 0x1a, 0x36, 0x05, + 0x14, 0x94, 0x26, 0xc9, 0xa5, 0x56, 0xb3, 0xe1, 0xf2, 0xb7, 0x03, 0xa3, 0xe7, 0x9c, 0xb3, 0x59, + 0xfa, 0x43, 0x96, 0x14, 0x73, 0x2c, 0xc9, 0x6c, 0x43, 0x37, 0xca, 0x0a, 0xf3, 0x7d, 0xbb, 0x81, + 0xde, 0xac, 0xcc, 0x5a, 0xa7, 0x31, 0x6b, 0x2b, 0xd3, 0xea, 0x36, 0xa7, 0xd5, 0x9a, 0xc6, 0x0d, + 0x7b, 0x1a, 0xc9, 0xc7, 0x30, 0x90, 0xf4, 0xa6, 0x11, 0xa6, 0x02, 0x73, 0xc5, 0xc0, 0x0b, 0x40, + 0x9a, 0x8e, 0x94, 0x85, 0x5e, 0xc1, 0x76, 0xbd, 0x50, 0xd3, 0x8b, 0x6b, 0xf5, 0x52, 0x4a, 0x51, + 0x9e, 0x98, 0x2a, 0xe5, 0x52, 0x0d, 0x70, 0x71, 0x9e, 0xb0, 0x68, 0x2a, 0x0f, 0x5c, 0x33, 0xc0, + 0xca, 0x72, 0x96, 0x27, 0x4b, 0xce, 0x1b, 0x16, 0x67, 0xfa, 0x05, 0x8c, 0xf4, 0x0b, 0x58, 0xbf, + 0xa0, 0x5d, 0x80, 0x2b, 0x65, 0x98, 0xb2, 0x58, 0xbf, 0x44, 0x5e, 0xe0, 0x69, 0xcb, 0xab, 0x98, + 0xd3, 0x6f, 0xc0, 0x3b, 0xc9, 0x34, 0x67, 0x4e, 0x0e, 0xc0, 0x4b, 0xca, 0x8d, 0x79, 0xb4, 0xc8, + 0xb2, 0xe5, 0x4a, 0xbf, 0x60, 0xe9, 0x44, 0xbf, 0x86, 0x7e, 0x69, 0x2e, 0x79, 0x38, 0xeb, 0x78, + 0x74, 0x56, 0x78, 0xd0, 0x7f, 0x1d, 0xd8, 0xae, 0x97, 0x6c, 0xae, 0xea, 0x0c, 0xb6, 0xaa, 0x14, + 0xd3, 0x79, 0xb8, 0x30, 0xb5, 0x1c, 0xd8, 0xb5, 0x34, 0xc3, 0xaa, 0x02, 0xf9, 0xeb, 0x70, 0xa1, + 0xbb, 0x67, 0x98, 0x58, 0xa6, 0xf1, 0xf7, 0xf0, 0x61, 0xc3, 0x45, 0x56, 0x7d, 0x89, 0xe5, 0x1c, + 0xc8, 0x25, 0x79, 0x0a, 0xdd, 0xab, 0x30, 0x29, 0xd0, 0x0c, 0xdd, 0xa8, 0x79, 0x03, 0x3c, 0xd0, + 0x1e, 0x5f, 0x75, 0x9e, 0x39, 0xf4, 0x4b, 0xb8, 0xaf, 0x1b, 0xf6, 0xa8, 0xea, 0xaf, 0xf2, 0xee, + 0xeb, 0x6d, 0xe8, 0xac, 0xb6, 0x21, 0x1d, 0x83, 0xdf, 0x0c, 0xd5, 0x64, 0x0e, 0xff, 0xec, 0xc1, + 0xf0, 0x14, 0xc3, 0x5f, 0x11, 0x63, 0xa9, 0x6c, 0x39, 0x99, 0x95, 0x97, 0x55, 0xff, 0x85, 0x43, + 0x9e, 0xac, 0xde, 0x4a, 0xeb, 0x4f, 0xaa, 0xf1, 0xa7, 0x6f, 0x73, 0x33, 0x83, 0x76, 0x8b, 0x9c, + 0xc0, 0xc0, 0xfa, 0x3d, 0x43, 0x76, 0xac, 0xc0, 0xc6, 0x4f, 0xa3, 0xf1, 0xee, 0x9a, 0xd3, 0x0a, + 0x2d, 0x04, 0xd2, 0x7c, 0x53, 0xc8, 0x27, 0xcb, 0xb0, 0xb5, 0x6f, 0xdb, 0xf8, 0xf1, 0xcd, 0x4e, + 0x76, 0xc1, 0x96, 0xe0, 0xda, 0x05, 0x37, 0x25, 0xde, 0x2e, 0xb8, 0x4d, 0xa5, 0x15, 0x9a, 0x25, + 0xa6, 0x36, 0x5a, 0x53, 0xbe, 0x6d, 0xb4, 0x36, 0x05, 0x56, 0x68, 0x96, 0x9c, 0xd9, 0x68, 0x4d, + 0x65, 0xb6, 0xd1, 0xda, 0x34, 0xf0, 0x16, 0x79, 0x03, 0x43, 0x5b, 0x5b, 0x88, 0x15, 0xd0, 0x22, + 0x8e, 0xe3, 0x87, 0xeb, 0x8e, 0x6d, 0x40, 0x7b, 0x94, 0x6c, 0xc0, 0x16, 0x31, 0xb1, 0x01, 0xdb, + 0x26, 0x90, 0xde, 0x22, 0x3f, 0xc1, 0x9d, 0xd5, 0x96, 0x26, 0x8f, 0x56, 0x69, 0x35, 0x26, 0x65, + 0x4c, 0x6f, 0x72, 0x29, 0xc1, 0xcf, 0x7b, 0xea, 0x6f, 0xc4, 0xe7, 0xff, 0x05, 0x00, 0x00, 0xff, + 0xff, 0x45, 0xa6, 0x48, 0x98, 0x55, 0x0c, 0x00, 0x00, } diff --git a/weed/s3api/AmazonS3.xsd b/weed/s3api/AmazonS3.xsd new file mode 100644 index 000000000..8016a6a83 --- /dev/null +++ b/weed/s3api/AmazonS3.xsd @@ -0,0 +1,692 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsd:schema + xmlns:tns="http://s3.amazonaws.com/doc/2006-03-01/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified" + targetNamespace="http://s3.amazonaws.com/doc/2006-03-01/"> + + <xsd:element name="CreateBucket"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="MetadataEntry"> + <xsd:sequence> + <xsd:element name="Name" type="xsd:string"/> + <xsd:element name="Value" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="CreateBucketResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="CreateBucketReturn" type="tns:CreateBucketResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="Status"> + <xsd:sequence> + <xsd:element name="Code" type="xsd:int"/> + <xsd:element name="Description" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="Result"> + <xsd:sequence> + <xsd:element name="Status" type="tns:Status"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="CreateBucketResult"> + <xsd:sequence> + <xsd:element name="BucketName" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="DeleteBucket"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="DeleteBucketResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="DeleteBucketResponse" type="tns:Status"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="BucketLoggingStatus"> + <xsd:sequence> + <xsd:element name="LoggingEnabled" type="tns:LoggingSettings" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="LoggingSettings"> + <xsd:sequence> + <xsd:element name="TargetBucket" type="xsd:string"/> + <xsd:element name="TargetPrefix" type="xsd:string"/> + <xsd:element name="TargetGrants" type="tns:AccessControlList" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="GetBucketLoggingStatus"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetBucketLoggingStatusResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetBucketLoggingStatusResponse" type="tns:BucketLoggingStatus"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetBucketLoggingStatus"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + <xsd:element name="BucketLoggingStatus" type="tns:BucketLoggingStatus"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetBucketLoggingStatusResponse"> + <xsd:complexType> + <xsd:sequence/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObjectAccessControlPolicy"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObjectAccessControlPolicyResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetObjectAccessControlPolicyResponse" type="tns:AccessControlPolicy"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetBucketAccessControlPolicy"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetBucketAccessControlPolicyResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetBucketAccessControlPolicyResponse" type="tns:AccessControlPolicy"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType abstract="true" name="Grantee"/> + + <xsd:complexType name="User" abstract="true"> + <xsd:complexContent> + <xsd:extension base="tns:Grantee"/> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="AmazonCustomerByEmail"> + <xsd:complexContent> + <xsd:extension base="tns:User"> + <xsd:sequence> + <xsd:element name="EmailAddress" type="xsd:string"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="CanonicalUser"> + <xsd:complexContent> + <xsd:extension base="tns:User"> + <xsd:sequence> + <xsd:element name="ID" type="xsd:string"/> + <xsd:element name="DisplayName" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:complexType name="Group"> + <xsd:complexContent> + <xsd:extension base="tns:Grantee"> + <xsd:sequence> + <xsd:element name="URI" type="xsd:string"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:simpleType name="Permission"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="READ"/> + <xsd:enumeration value="WRITE"/> + <xsd:enumeration value="READ_ACP"/> + <xsd:enumeration value="WRITE_ACP"/> + <xsd:enumeration value="FULL_CONTROL"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="StorageClass"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="STANDARD"/> + <xsd:enumeration value="REDUCED_REDUNDANCY"/> + <xsd:enumeration value="GLACIER"/> + <xsd:enumeration value="UNKNOWN"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="Grant"> + <xsd:sequence> + <xsd:element name="Grantee" type="tns:Grantee"/> + <xsd:element name="Permission" type="tns:Permission"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="AccessControlList"> + <xsd:sequence> + <xsd:element name="Grant" type="tns:Grant" minOccurs="0" maxOccurs="100"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="CreateBucketConfiguration"> + <xsd:sequence> + <xsd:element name="LocationConstraint" type="tns:LocationConstraint"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="LocationConstraint"> + <xsd:simpleContent> + <xsd:extension base="xsd:string"/> + </xsd:simpleContent> + </xsd:complexType> + + <xsd:complexType name="AccessControlPolicy"> + <xsd:sequence> + <xsd:element name="Owner" type="tns:CanonicalUser"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="SetObjectAccessControlPolicy"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetObjectAccessControlPolicyResponse"> + <xsd:complexType> + <xsd:sequence/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetBucketAccessControlPolicy"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="SetBucketAccessControlPolicyResponse"> + <xsd:complexType> + <xsd:sequence/> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObject"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="GetMetadata" type="xsd:boolean"/> + <xsd:element name="GetData" type="xsd:boolean"/> + <xsd:element name="InlineData" type="xsd:boolean"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObjectResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetObjectResponse" type="tns:GetObjectResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="GetObjectResult"> + <xsd:complexContent> + <xsd:extension base="tns:Result"> + <xsd:sequence> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="Data" type="xsd:base64Binary" nillable="true"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="ETag" type="xsd:string"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + + <xsd:element name="GetObjectExtended"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="GetMetadata" type="xsd:boolean"/> + <xsd:element name="GetData" type="xsd:boolean"/> + <xsd:element name="InlineData" type="xsd:boolean"/> + <xsd:element name="ByteRangeStart" type="xsd:long" minOccurs="0"/> + <xsd:element name="ByteRangeEnd" type="xsd:long" minOccurs="0"/> + <xsd:element name="IfModifiedSince" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="IfUnmodifiedSince" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="IfMatch" type="xsd:string" minOccurs="0" maxOccurs="100"/> + <xsd:element name="IfNoneMatch" type="xsd:string" minOccurs="0" maxOccurs="100"/> + <xsd:element name="ReturnCompleteObjectOnConditionFailure" type="xsd:boolean" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="GetObjectExtendedResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="GetObjectResponse" type="tns:GetObjectResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="PutObject"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="100"/> + <xsd:element name="ContentLength" type="xsd:long"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="StorageClass" type="tns:StorageClass" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="PutObjectResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="PutObjectResponse" type="tns:PutObjectResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="PutObjectResult"> + <xsd:sequence> + <xsd:element name="ETag" type="xsd:string"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="PutObjectInline"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element minOccurs="0" maxOccurs="100" name="Metadata" type="tns:MetadataEntry"/> + <xsd:element name="Data" type="xsd:base64Binary"/> + <xsd:element name="ContentLength" type="xsd:long"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="StorageClass" type="tns:StorageClass" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="PutObjectInlineResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="PutObjectInlineResponse" type="tns:PutObjectResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="DeleteObject"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="DeleteObjectResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="DeleteObjectResponse" type="tns:Status"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="ListBucket"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Prefix" type="xsd:string" minOccurs="0"/> + <xsd:element name="Marker" type="xsd:string" minOccurs="0"/> + <xsd:element name="MaxKeys" type="xsd:int" minOccurs="0"/> + <xsd:element name="Delimiter" type="xsd:string" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="ListBucketResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="ListBucketResponse" type="tns:ListBucketResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="ListVersionsResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="ListVersionsResponse" type="tns:ListVersionsResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="ListEntry"> + <xsd:sequence> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="ETag" type="xsd:string"/> + <xsd:element name="Size" type="xsd:long"/> + <xsd:element name="Owner" type="tns:CanonicalUser" minOccurs="0"/> + <xsd:element name="StorageClass" type="tns:StorageClass"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="VersionEntry"> + <xsd:sequence> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="VersionId" type="xsd:string"/> + <xsd:element name="IsLatest" type="xsd:boolean"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="ETag" type="xsd:string"/> + <xsd:element name="Size" type="xsd:long"/> + <xsd:element name="Owner" type="tns:CanonicalUser" minOccurs="0"/> + <xsd:element name="StorageClass" type="tns:StorageClass"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="DeleteMarkerEntry"> + <xsd:sequence> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="VersionId" type="xsd:string"/> + <xsd:element name="IsLatest" type="xsd:boolean"/> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="Owner" type="tns:CanonicalUser" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="PrefixEntry"> + <xsd:sequence> + <xsd:element name="Prefix" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ListBucketResult"> + <xsd:sequence> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="Name" type="xsd:string"/> + <xsd:element name="Prefix" type="xsd:string"/> + <xsd:element name="Marker" type="xsd:string"/> + <xsd:element name="NextMarker" type="xsd:string" minOccurs="0"/> + <xsd:element name="MaxKeys" type="xsd:int"/> + <xsd:element name="Delimiter" type="xsd:string" minOccurs="0"/> + <xsd:element name="IsTruncated" type="xsd:boolean"/> + <xsd:element name="Contents" type="tns:ListEntry" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="CommonPrefixes" type="tns:PrefixEntry" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ListVersionsResult"> + <xsd:sequence> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="unbounded"/> + <xsd:element name="Name" type="xsd:string"/> + <xsd:element name="Prefix" type="xsd:string"/> + <xsd:element name="KeyMarker" type="xsd:string"/> + <xsd:element name="VersionIdMarker" type="xsd:string"/> + <xsd:element name="NextKeyMarker" type="xsd:string" minOccurs="0"/> + <xsd:element name="NextVersionIdMarker" type="xsd:string" minOccurs="0"/> + <xsd:element name="MaxKeys" type="xsd:int"/> + <xsd:element name="Delimiter" type="xsd:string" minOccurs="0"/> + <xsd:element name="IsTruncated" type="xsd:boolean"/> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="Version" type="tns:VersionEntry"/> + <xsd:element name="DeleteMarker" type="tns:DeleteMarkerEntry"/> + </xsd:choice> + <xsd:element name="CommonPrefixes" type="tns:PrefixEntry" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="ListAllMyBuckets"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="ListAllMyBucketsResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="ListAllMyBucketsResponse" type="tns:ListAllMyBucketsResult"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="ListAllMyBucketsEntry"> + <xsd:sequence> + <xsd:element name="Name" type="xsd:string"/> + <xsd:element name="CreationDate" type="xsd:dateTime"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ListAllMyBucketsResult"> + <xsd:sequence> + <xsd:element name="Owner" type="tns:CanonicalUser"/> + <xsd:element name="Buckets" type="tns:ListAllMyBucketsList"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="ListAllMyBucketsList"> + <xsd:sequence> + <xsd:element name="Bucket" type="tns:ListAllMyBucketsEntry" minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="PostResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="Location" type="xsd:anyURI"/> + <xsd:element name="Bucket" type="xsd:string"/> + <xsd:element name="Key" type="xsd:string"/> + <xsd:element name="ETag" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:simpleType name="MetadataDirective"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="COPY"/> + <xsd:enumeration value="REPLACE"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:element name="CopyObject"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="SourceBucket" type="xsd:string"/> + <xsd:element name="SourceKey" type="xsd:string"/> + <xsd:element name="DestinationBucket" type="xsd:string"/> + <xsd:element name="DestinationKey" type="xsd:string"/> + <xsd:element name="MetadataDirective" type="tns:MetadataDirective" minOccurs="0"/> + <xsd:element name="Metadata" type="tns:MetadataEntry" minOccurs="0" maxOccurs="100"/> + <xsd:element name="AccessControlList" type="tns:AccessControlList" minOccurs="0"/> + <xsd:element name="CopySourceIfModifiedSince" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="CopySourceIfUnmodifiedSince" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="CopySourceIfMatch" type="xsd:string" minOccurs="0" maxOccurs="100"/> + <xsd:element name="CopySourceIfNoneMatch" type="xsd:string" minOccurs="0" maxOccurs="100"/> + <xsd:element name="StorageClass" type="tns:StorageClass" minOccurs="0"/> + <xsd:element name="AWSAccessKeyId" type="xsd:string" minOccurs="0"/> + <xsd:element name="Timestamp" type="xsd:dateTime" minOccurs="0"/> + <xsd:element name="Signature" type="xsd:string" minOccurs="0"/> + <xsd:element name="Credential" type="xsd:string" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:element name="CopyObjectResponse"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="CopyObjectResult" type="tns:CopyObjectResult" /> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="CopyObjectResult"> + <xsd:sequence> + <xsd:element name="LastModified" type="xsd:dateTime"/> + <xsd:element name="ETag" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="RequestPaymentConfiguration"> + <xsd:sequence> + <xsd:element name="Payer" type="tns:Payer" minOccurs="1" maxOccurs="1"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:simpleType name="Payer"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="BucketOwner"/> + <xsd:enumeration value="Requester"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="VersioningConfiguration"> + <xsd:sequence> + <xsd:element name="Status" type="tns:VersioningStatus" minOccurs="0"/> + <xsd:element name="MfaDelete" type="tns:MfaDeleteStatus" minOccurs="0"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:simpleType name="MfaDeleteStatus"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="Enabled"/> + <xsd:enumeration value="Disabled"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:simpleType name="VersioningStatus"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="Enabled"/> + <xsd:enumeration value="Suspended"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="NotificationConfiguration"> + <xsd:sequence> + <xsd:element name="TopicConfiguration" minOccurs="0" maxOccurs="unbounded" type="tns:TopicConfiguration"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="TopicConfiguration"> + <xsd:sequence> + <xsd:element name="Topic" minOccurs="1" maxOccurs="1" type="xsd:string"/> + <xsd:element name="Event" minOccurs="1" maxOccurs="unbounded" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + +</xsd:schema>
\ No newline at end of file diff --git a/weed/s3api/README.txt b/weed/s3api/README.txt new file mode 100644 index 000000000..10a18ff4d --- /dev/null +++ b/weed/s3api/README.txt @@ -0,0 +1,7 @@ +see https://blog.aqwari.net/xml-schema-go/ + +1. go get aqwari.net/xml/cmd/xsdgen +2. xsdgen -o s3api_xsd_generated.go -pkg s3api AmazonS3.xsd + + + diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go new file mode 100644 index 000000000..a2af1f70c --- /dev/null +++ b/weed/s3api/s3api_bucket_handlers.go @@ -0,0 +1,177 @@ +package s3api + +import ( + "net/http" + "github.com/chrislusf/seaweedfs/weed/pb/filer_pb" + "github.com/chrislusf/seaweedfs/weed/glog" + "time" + "context" + "fmt" + "github.com/gorilla/mux" + "os" +) + +var ( + OS_UID = uint32(os.Getuid()) + OS_GID = uint32(os.Getgid()) +) + +func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Request) { + + var response ListAllMyBucketsResponse + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + request := &filer_pb.ListEntriesRequest{ + Directory: s3a.option.BucketsPath, + } + + glog.V(4).Infof("read directory: %v", request) + resp, err := client.ListEntries(context.Background(), request) + if err != nil { + return fmt.Errorf("list buckets: %v", err) + } + + var buckets []ListAllMyBucketsEntry + for _, entry := range resp.Entries { + if entry.IsDirectory { + buckets = append(buckets, ListAllMyBucketsEntry{ + Name: entry.Name, + CreationDate: time.Unix(entry.Attributes.Crtime, 0), + }) + } + } + + response = ListAllMyBucketsResponse{ + ListAllMyBucketsResponse: ListAllMyBucketsResult{ + Owner: CanonicalUser{ + ID: "", + DisplayName: "", + }, + Buckets: ListAllMyBucketsList{ + Bucket: buckets, + }, + }, + } + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeSuccessResponseXML(w, encodeResponse(response)) +} + +func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + bucket := vars["bucket"] + + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + request := &filer_pb.CreateEntryRequest{ + Directory: s3a.option.BucketsPath, + Entry: &filer_pb.Entry{ + Name: bucket, + IsDirectory: true, + Attributes: &filer_pb.FuseAttributes{ + Mtime: time.Now().Unix(), + Crtime: time.Now().Unix(), + FileMode: uint32(0777 | os.ModeDir), + Uid: OS_UID, + Gid: OS_GID, + }, + }, + } + + glog.V(1).Infof("create bucket: %v", request) + if _, err := client.CreateEntry(context.Background(), request); err != nil { + return fmt.Errorf("mkdir %s/%s: %v", s3a.option.BucketsPath, bucket, err) + } + + // lazily create collection + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeSuccessResponseEmpty(w) +} + +func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + bucket := vars["bucket"] + + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + ctx := context.Background() + + // delete collection + deleteCollectionRequest := &filer_pb.DeleteCollectionRequest{ + Collection: bucket, + } + + glog.V(1).Infof("delete collection: %v", deleteCollectionRequest) + if _, err := client.DeleteCollection(ctx, deleteCollectionRequest); err != nil { + return fmt.Errorf("delete collection %s: %v", bucket, err) + } + + // delete bucket metadata + request := &filer_pb.DeleteEntryRequest{ + Directory: s3a.option.BucketsPath, + Name: bucket, + IsDirectory: true, + IsDeleteData: false, + IsRecursive: true, + } + + glog.V(1).Infof("delete bucket: %v", request) + if _, err := client.DeleteEntry(ctx, request); err != nil { + return fmt.Errorf("delete bucket %s/%s: %v", s3a.option.BucketsPath, bucket, err) + } + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeResponse(w, http.StatusNoContent, nil, mimeNone) +} + +func (s3a *S3ApiServer) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { + + vars := mux.Vars(r) + bucket := vars["bucket"] + + err := s3a.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + request := &filer_pb.LookupDirectoryEntryRequest{ + Directory: s3a.option.BucketsPath, + Name: bucket, + } + + glog.V(1).Infof("lookup bucket: %v", request) + if _, err := client.LookupDirectoryEntry(context.Background(), request); err != nil { + return fmt.Errorf("lookup bucket %s/%s: %v", s3a.option.BucketsPath, bucket, err) + } + + return nil + }) + + if err != nil { + writeErrorResponse(w, ErrNoSuchBucket, r.URL) + return + } + + writeSuccessResponseEmpty(w) +} diff --git a/weed/s3api/s3api_errors.go b/weed/s3api/s3api_errors.go new file mode 100644 index 000000000..10b48c2c8 --- /dev/null +++ b/weed/s3api/s3api_errors.go @@ -0,0 +1,88 @@ +package s3api + +import ( + "encoding/xml" + "net/http" +) + +// APIError structure +type APIError struct { + Code string + Description string + HTTPStatusCode int +} + +// RESTErrorResponse - error response format +type RESTErrorResponse struct { + XMLName xml.Name `xml:"Error" json:"-"` + Code string `xml:"Code" json:"Code"` + Message string `xml:"Message" json:"Message"` + Resource string `xml:"Resource" json:"Resource"` + RequestID string `xml:"RequestId" json:"RequestId"` +} + +// ErrorCode type of error status. +type ErrorCode int + +// Error codes, see full list at http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html +const ( + ErrNone ErrorCode = iota + ErrMethodNotAllowed + ErrBucketNotEmpty + ErrBucketAlreadyExists + ErrBucketAlreadyOwnedByYou + ErrNoSuchBucket + ErrInvalidBucketName + ErrInvalidDigest + ErrInternalError +) + +// error code to APIError structure, these fields carry respective +// descriptions for all the error responses. +var errorCodeResponse = map[ErrorCode]APIError{ + ErrMethodNotAllowed: { + Code: "MethodNotAllowed", + Description: "The specified method is not allowed against this resource.", + HTTPStatusCode: http.StatusMethodNotAllowed, + }, + ErrBucketNotEmpty: { + Code: "BucketNotEmpty", + Description: "The bucket you tried to delete is not empty", + HTTPStatusCode: http.StatusConflict, + }, + ErrBucketAlreadyExists: { + Code: "BucketAlreadyExists", + Description: "The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.", + HTTPStatusCode: http.StatusConflict, + }, + ErrBucketAlreadyOwnedByYou: { + Code: "BucketAlreadyOwnedByYou", + Description: "Your previous request to create the named bucket succeeded and you already own it.", + HTTPStatusCode: http.StatusConflict, + }, + ErrInvalidBucketName: { + Code: "InvalidBucketName", + Description: "The specified bucket is not valid.", + HTTPStatusCode: http.StatusBadRequest, + }, + ErrInvalidDigest: { + Code: "InvalidDigest", + Description: "The Content-Md5 you specified is not valid.", + HTTPStatusCode: http.StatusBadRequest, + }, + ErrNoSuchBucket: { + Code: "NoSuchBucket", + Description: "The specified bucket does not exist", + HTTPStatusCode: http.StatusNotFound, + }, + ErrInternalError: { + Code: "InternalError", + Description: "We encountered an internal error, please try again.", + HTTPStatusCode: http.StatusInternalServerError, + }, +} + +// getAPIError provides API Error for input API error code. +func getAPIError(code ErrorCode) APIError { + return errorCodeResponse[code] +} diff --git a/weed/s3api/s3api_handlers.go b/weed/s3api/s3api_handlers.go new file mode 100644 index 000000000..13dfc8d15 --- /dev/null +++ b/weed/s3api/s3api_handlers.go @@ -0,0 +1,107 @@ +package s3api + +import ( + "net/http" + "net/url" + "fmt" + "time" + "github.com/gorilla/mux" + "context" + "github.com/chrislusf/seaweedfs/weed/pb/filer_pb" + "github.com/chrislusf/seaweedfs/weed/util" + "bytes" + "encoding/xml" + "encoding/base64" +) + +type mimeType string + +const ( + mimeNone mimeType = "" + mimeJSON mimeType = "application/json" + mimeXML mimeType = "application/xml" +) + +func setCommonHeaders(w http.ResponseWriter) { + w.Header().Set("x-amz-request-id", fmt.Sprintf("%d", time.Now().UnixNano())) + w.Header().Set("Accept-Ranges", "bytes") +} + +// Encodes the response headers into XML format. +func encodeResponse(response interface{}) []byte { + var bytesBuffer bytes.Buffer + bytesBuffer.WriteString(xml.Header) + e := xml.NewEncoder(&bytesBuffer) + e.Encode(response) + return bytesBuffer.Bytes() +} + +func newContext(r *http.Request, api string) context.Context { + vars := mux.Vars(r) + return context.WithValue(context.Background(), "bucket", vars["bucket"]) +} + +func (s3a *S3ApiServer) withFilerClient(fn func(filer_pb.SeaweedFilerClient) error) error { + + grpcConnection, err := util.GrpcDial(s3a.option.FilerGrpcAddress) + if err != nil { + return fmt.Errorf("fail to dial %s: %v", s3a.option.FilerGrpcAddress, err) + } + defer grpcConnection.Close() + + client := filer_pb.NewSeaweedFilerClient(grpcConnection) + + return fn(client) +} + +// If none of the http routes match respond with MethodNotAllowed +func notFoundHandler(w http.ResponseWriter, r *http.Request) { + writeErrorResponse(w, ErrMethodNotAllowed, r.URL) +} + +func writeErrorResponse(w http.ResponseWriter, errorCode ErrorCode, reqURL *url.URL) { + apiError := getAPIError(errorCode) + errorResponse := getRESTErrorResponse(apiError, reqURL.Path) + encodedErrorResponse := encodeResponse(errorResponse) + writeResponse(w, apiError.HTTPStatusCode, encodedErrorResponse, mimeXML) +} + +func getRESTErrorResponse(err APIError, resource string) RESTErrorResponse { + return RESTErrorResponse{ + Code: err.Code, + Message: err.Description, + Resource: resource, + RequestID: fmt.Sprintf("%d", time.Now().UnixNano()), + } +} + +func writeResponse(w http.ResponseWriter, statusCode int, response []byte, mType mimeType) { + setCommonHeaders(w) + if mType != mimeNone { + w.Header().Set("Content-Type", string(mType)) + } + w.WriteHeader(statusCode) + if response != nil { + w.Write(response) + w.(http.Flusher).Flush() + } +} + +func writeSuccessResponseXML(w http.ResponseWriter, response []byte) { + writeResponse(w, http.StatusOK, response, mimeXML) +} + +func writeSuccessResponseEmpty(w http.ResponseWriter) { + writeResponse(w, http.StatusOK, nil, mimeNone) +} + +func validateContentMd5(h http.Header) ([]byte, error) { + md5B64, ok := h["Content-Md5"] + if ok { + if md5B64[0] == "" { + return nil, fmt.Errorf("Content-Md5 header set to empty value") + } + return base64.StdEncoding.DecodeString(md5B64[0]) + } + return []byte{}, nil +} diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go new file mode 100644 index 000000000..079509792 --- /dev/null +++ b/weed/s3api/s3api_object_handlers.go @@ -0,0 +1,90 @@ +package s3api + +import ( + "net/http" + "github.com/chrislusf/seaweedfs/weed/glog" + "fmt" + "github.com/gorilla/mux" + "io/ioutil" + "encoding/json" +) + +var ( + client *http.Client +) + +func init() { + client = &http.Client{Transport: &http.Transport{ + MaxIdleConnsPerHost: 1024, + }} +} + +type UploadResult struct { + Name string `json:"name,omitempty"` + Size uint32 `json:"size,omitempty"` + Error string `json:"error,omitempty"` +} + +func (s3a *S3ApiServer) PutObjectHandler(w http.ResponseWriter, r *http.Request) { + + // http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html + + vars := mux.Vars(r) + bucket := vars["bucket"] + object := vars["object"] + + _, err := validateContentMd5(r.Header) + if err != nil { + writeErrorResponse(w, ErrInvalidDigest, r.URL) + return + } + + uploadUrl := fmt.Sprintf("http://%s%s/%s/%s?collection=%s", + s3a.option.Filer, s3a.option.BucketsPath, bucket, object, bucket) + proxyReq, err := http.NewRequest("PUT", uploadUrl, r.Body) + + if err != nil { + glog.Errorf("NewRequest %s: %v", uploadUrl, err) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + proxyReq.Header.Set("Host", s3a.option.Filer) + proxyReq.Header.Set("X-Forwarded-For", r.RemoteAddr) + + for header, values := range r.Header { + for _, value := range values { + proxyReq.Header.Add(header, value) + } + } + + resp, postErr := client.Do(proxyReq) + + if postErr != nil { + glog.Errorf("post to filer: %v", postErr) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + defer resp.Body.Close() + + resp_body, ra_err := ioutil.ReadAll(resp.Body) + if ra_err != nil { + glog.Errorf("upload to filer response read: %v", ra_err) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + var ret UploadResult + unmarshal_err := json.Unmarshal(resp_body, &ret) + if unmarshal_err != nil { + glog.Errorf("failing to read upload to %s : %v", uploadUrl, string(resp_body)) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + if ret.Error != "" { + glog.Errorf("upload to filer error: %v", ret.Error) + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + writeSuccessResponseEmpty(w) +} diff --git a/weed/s3api/s3api_server.go b/weed/s3api/s3api_server.go new file mode 100644 index 000000000..d8e6de1f7 --- /dev/null +++ b/weed/s3api/s3api_server.go @@ -0,0 +1,115 @@ +package s3api + +import ( + _ "github.com/chrislusf/seaweedfs/weed/filer2/cassandra" + _ "github.com/chrislusf/seaweedfs/weed/filer2/leveldb" + _ "github.com/chrislusf/seaweedfs/weed/filer2/memdb" + _ "github.com/chrislusf/seaweedfs/weed/filer2/mysql" + _ "github.com/chrislusf/seaweedfs/weed/filer2/postgres" + _ "github.com/chrislusf/seaweedfs/weed/filer2/redis" + "github.com/gorilla/mux" + "net/http" +) + +type S3ApiServerOption struct { + Filer string + FilerGrpcAddress string + DomainName string + BucketsPath string +} + +type S3ApiServer struct { + option *S3ApiServerOption +} + +func NewS3ApiServer(router *mux.Router, option *S3ApiServerOption) (s3ApiServer *S3ApiServer, err error) { + s3ApiServer = &S3ApiServer{ + option: option, + } + + s3ApiServer.registerRouter(router) + + return s3ApiServer, nil +} + +func (s3a *S3ApiServer) registerRouter(router *mux.Router) { + // API Router + apiRouter := router.PathPrefix("/").Subrouter() + var routers []*mux.Router + if s3a.option.DomainName != "" { + routers = append(routers, apiRouter.Host("{bucket:.+}." + s3a.option.DomainName).Subrouter()) + } + routers = append(routers, apiRouter.PathPrefix("/{bucket}").Subrouter()) + + for _, bucket := range routers { + + // PutObject + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectHandler) + + // PutBucket + bucket.Methods("PUT").HandlerFunc(s3a.PutBucketHandler) + // DeleteBucket + bucket.Methods("DELETE").HandlerFunc(s3a.DeleteBucketHandler) + // HeadBucket + bucket.Methods("HEAD").HandlerFunc(s3a.HeadBucketHandler) + + /* + // HeadObject + bucket.Methods("HEAD").Path("/{object:.+}").HandlerFunc(s3a.HeadObjectHandler) + // GetObject + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.GetObjectHandler) + // CopyObject + bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(s3a.CopyObjectHandler) + // PutObject + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectHandler) + // DeleteObject + bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(s3a.DeleteObjectHandler) + + // CopyObjectPart + bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(s3a.CopyObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") + // PutObjectPart + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(s3a.PutObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") + // ListObjectPxarts + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.ListObjectPartsHandler).Queries("uploadId", "{uploadId:.*}") + // CompleteMultipartUpload + bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(s3a.CompleteMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") + // NewMultipartUpload + bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(s3a.NewMultipartUploadHandler).Queries("uploads", "") + // AbortMultipartUpload + bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(s3a.AbortMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") + + // ListMultipartUploads + bucket.Methods("GET").HandlerFunc(s3a.ListMultipartUploadsHandler).Queries("uploads", "") + // ListObjectsV2 + bucket.Methods("GET").HandlerFunc(s3a.ListObjectsV2Handler).Queries("list-type", "2") + // ListObjectsV1 (Legacy) + bucket.Methods("GET").HandlerFunc(s3a.ListObjectsV1Handler) + // DeleteMultipleObjects + bucket.Methods("POST").HandlerFunc(s3a.DeleteMultipleObjectsHandler).Queries("delete", "") + + // not implemented + // GetBucketLocation + bucket.Methods("GET").HandlerFunc(s3a.GetBucketLocationHandler).Queries("location", "") + // GetBucketPolicy + bucket.Methods("GET").HandlerFunc(s3a.GetBucketPolicyHandler).Queries("policy", "") + // GetObjectACL + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(s3a.GetObjectACLHandler).Queries("acl", "") + // GetBucketACL + bucket.Methods("GET").HandlerFunc(s3a.GetBucketACLHandler).Queries("acl", "") + // PutBucketPolicy + bucket.Methods("PUT").HandlerFunc(s3a.PutBucketPolicyHandler).Queries("policy", "") + // DeleteBucketPolicy + bucket.Methods("DELETE").HandlerFunc(s3a.DeleteBucketPolicyHandler).Queries("policy", "") + // PostPolicy + bucket.Methods("POST").HeadersRegexp("Content-Type", "multipart/form-data*").HandlerFunc(s3a.PostPolicyBucketHandler) + */ + + } + + // ListBuckets + apiRouter.Methods("GET").Path("/").HandlerFunc(s3a.ListBucketsHandler) + + // NotFound + apiRouter.NotFoundHandler = http.HandlerFunc(notFoundHandler) + +} diff --git a/weed/s3api/s3api_xsd_generated.go b/weed/s3api/s3api_xsd_generated.go new file mode 100644 index 000000000..915b74ec4 --- /dev/null +++ b/weed/s3api/s3api_xsd_generated.go @@ -0,0 +1,1002 @@ +package s3api + +import ( + "bytes" + "encoding/base64" + "encoding/xml" + "time" +) + +type AccessControlList struct { + Grant []Grant `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Grant,omitempty"` +} + +type AccessControlPolicy struct { + Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner"` + AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList"` +} + +type AmazonCustomerByEmail struct { + EmailAddress string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ EmailAddress"` +} + +type BucketLoggingStatus struct { + LoggingEnabled LoggingSettings `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LoggingEnabled,omitempty"` +} + +type CanonicalUser struct { + ID string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ID"` + DisplayName string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DisplayName,omitempty"` +} + +type CopyObject struct { + SourceBucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ SourceBucket"` + SourceKey string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ SourceKey"` + DestinationBucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DestinationBucket"` + DestinationKey string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DestinationKey"` + MetadataDirective MetadataDirective `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MetadataDirective,omitempty"` + Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"` + AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,omitempty"` + CopySourceIfModifiedSince time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfModifiedSince,omitempty"` + CopySourceIfUnmodifiedSince time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfUnmodifiedSince,omitempty"` + CopySourceIfMatch []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfMatch,omitempty"` + CopySourceIfNoneMatch []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfNoneMatch,omitempty"` + StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass,omitempty"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *CopyObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T CopyObject + var layout struct { + *T + CopySourceIfModifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfModifiedSince,omitempty"` + CopySourceIfUnmodifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfUnmodifiedSince,omitempty"` + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.CopySourceIfModifiedSince = (*xsdDateTime)(&layout.T.CopySourceIfModifiedSince) + layout.CopySourceIfUnmodifiedSince = (*xsdDateTime)(&layout.T.CopySourceIfUnmodifiedSince) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *CopyObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T CopyObject + var overlay struct { + *T + CopySourceIfModifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfModifiedSince,omitempty"` + CopySourceIfUnmodifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopySourceIfUnmodifiedSince,omitempty"` + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.CopySourceIfModifiedSince = (*xsdDateTime)(&overlay.T.CopySourceIfModifiedSince) + overlay.CopySourceIfUnmodifiedSince = (*xsdDateTime)(&overlay.T.CopySourceIfUnmodifiedSince) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type CopyObjectResponse struct { + CopyObjectResult CopyObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CopyObjectResult"` +} + +type CopyObjectResult struct { + LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` +} + +func (t *CopyObjectResult) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T CopyObjectResult + var layout struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + layout.T = (*T)(t) + layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) + return e.EncodeElement(layout, start) +} +func (t *CopyObjectResult) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T CopyObjectResult + var overlay struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + overlay.T = (*T)(t) + overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) + return d.DecodeElement(&overlay, &start) +} + +type CreateBucket struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,omitempty"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` +} + +func (t *CreateBucket) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T CreateBucket + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *CreateBucket) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T CreateBucket + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type CreateBucketConfiguration struct { + LocationConstraint string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LocationConstraint"` +} + +type CreateBucketResponse struct { + CreateBucketReturn CreateBucketResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreateBucketReturn"` +} + +type CreateBucketResult struct { + BucketName string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ BucketName"` +} + +type DeleteBucket struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *DeleteBucket) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T DeleteBucket + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *DeleteBucket) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T DeleteBucket + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type DeleteBucketResponse struct { + DeleteBucketResponse Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteBucketResponse"` +} + +type DeleteMarkerEntry struct { + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + VersionId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersionId"` + IsLatest bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsLatest"` + LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner,omitempty"` +} + +func (t *DeleteMarkerEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T DeleteMarkerEntry + var layout struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + layout.T = (*T)(t) + layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) + return e.EncodeElement(layout, start) +} +func (t *DeleteMarkerEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T DeleteMarkerEntry + var overlay struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + overlay.T = (*T)(t) + overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) + return d.DecodeElement(&overlay, &start) +} + +type DeleteObject struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *DeleteObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T DeleteObject + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *DeleteObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T DeleteObject + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type DeleteObjectResponse struct { + DeleteObjectResponse Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteObjectResponse"` +} + +type GetBucketAccessControlPolicy struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *GetBucketAccessControlPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T GetBucketAccessControlPolicy + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *GetBucketAccessControlPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T GetBucketAccessControlPolicy + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type GetBucketAccessControlPolicyResponse struct { + GetBucketAccessControlPolicyResponse AccessControlPolicy `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetBucketAccessControlPolicyResponse"` +} + +type GetBucketLoggingStatus struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *GetBucketLoggingStatus) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T GetBucketLoggingStatus + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *GetBucketLoggingStatus) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T GetBucketLoggingStatus + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type GetBucketLoggingStatusResponse struct { + GetBucketLoggingStatusResponse BucketLoggingStatus `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetBucketLoggingStatusResponse"` +} + +type GetObject struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + GetMetadata bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetMetadata"` + GetData bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetData"` + InlineData bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ InlineData"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *GetObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T GetObject + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *GetObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T GetObject + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type GetObjectAccessControlPolicy struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *GetObjectAccessControlPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T GetObjectAccessControlPolicy + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *GetObjectAccessControlPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T GetObjectAccessControlPolicy + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type GetObjectAccessControlPolicyResponse struct { + GetObjectAccessControlPolicyResponse AccessControlPolicy `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetObjectAccessControlPolicyResponse"` +} + +type GetObjectExtended struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + GetMetadata bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetMetadata"` + GetData bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetData"` + InlineData bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ InlineData"` + ByteRangeStart int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ByteRangeStart,omitempty"` + ByteRangeEnd int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ByteRangeEnd,omitempty"` + IfModifiedSince time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfModifiedSince,omitempty"` + IfUnmodifiedSince time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfUnmodifiedSince,omitempty"` + IfMatch []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfMatch,omitempty"` + IfNoneMatch []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfNoneMatch,omitempty"` + ReturnCompleteObjectOnConditionFailure bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ReturnCompleteObjectOnConditionFailure,omitempty"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *GetObjectExtended) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T GetObjectExtended + var layout struct { + *T + IfModifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfModifiedSince,omitempty"` + IfUnmodifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfUnmodifiedSince,omitempty"` + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.IfModifiedSince = (*xsdDateTime)(&layout.T.IfModifiedSince) + layout.IfUnmodifiedSince = (*xsdDateTime)(&layout.T.IfUnmodifiedSince) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *GetObjectExtended) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T GetObjectExtended + var overlay struct { + *T + IfModifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfModifiedSince,omitempty"` + IfUnmodifiedSince *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IfUnmodifiedSince,omitempty"` + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.IfModifiedSince = (*xsdDateTime)(&overlay.T.IfModifiedSince) + overlay.IfUnmodifiedSince = (*xsdDateTime)(&overlay.T.IfUnmodifiedSince) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type GetObjectExtendedResponse struct { + GetObjectResponse GetObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetObjectResponse"` +} + +type GetObjectResponse struct { + GetObjectResponse GetObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ GetObjectResponse"` +} + +type GetObjectResult struct { + Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"` + Data []byte `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data,omitempty"` + LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` + Status Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Status"` +} + +func (t *GetObjectResult) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T GetObjectResult + var layout struct { + *T + Data *xsdBase64Binary `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data,omitempty"` + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + layout.T = (*T)(t) + layout.Data = (*xsdBase64Binary)(&layout.T.Data) + layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) + return e.EncodeElement(layout, start) +} +func (t *GetObjectResult) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T GetObjectResult + var overlay struct { + *T + Data *xsdBase64Binary `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data,omitempty"` + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + overlay.T = (*T)(t) + overlay.Data = (*xsdBase64Binary)(&overlay.T.Data) + overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) + return d.DecodeElement(&overlay, &start) +} + +type Grant struct { + Grantee Grantee `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Grantee"` + Permission Permission `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Permission"` +} + +type Grantee struct { +} + +type Group struct { + URI string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ URI"` +} + +type ListAllMyBuckets struct { + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` +} + +func (t *ListAllMyBuckets) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T ListAllMyBuckets + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *ListAllMyBuckets) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T ListAllMyBuckets + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type ListAllMyBucketsEntry struct { + Name string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Name"` + CreationDate time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreationDate"` +} + +func (t *ListAllMyBucketsEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T ListAllMyBucketsEntry + var layout struct { + *T + CreationDate *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreationDate"` + } + layout.T = (*T)(t) + layout.CreationDate = (*xsdDateTime)(&layout.T.CreationDate) + return e.EncodeElement(layout, start) +} +func (t *ListAllMyBucketsEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T ListAllMyBucketsEntry + var overlay struct { + *T + CreationDate *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreationDate"` + } + overlay.T = (*T)(t) + overlay.CreationDate = (*xsdDateTime)(&overlay.T.CreationDate) + return d.DecodeElement(&overlay, &start) +} + +type ListAllMyBucketsList struct { + Bucket []ListAllMyBucketsEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket,omitempty"` +} + +type ListAllMyBucketsResponse struct { + ListAllMyBucketsResponse ListAllMyBucketsResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResponse"` +} + +type ListAllMyBucketsResult struct { + Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner"` + Buckets ListAllMyBucketsList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Buckets"` +} + +type ListBucket struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix,omitempty"` + Marker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Marker,omitempty"` + MaxKeys int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxKeys,omitempty"` + Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter,omitempty"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *ListBucket) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T ListBucket + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *ListBucket) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T ListBucket + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type ListBucketResponse struct { + ListBucketResponse ListBucketResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListBucketResponse"` +} + +type ListBucketResult struct { + Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"` + Name string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Name"` + Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"` + Marker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Marker"` + NextMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextMarker,omitempty"` + MaxKeys int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxKeys"` + Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter,omitempty"` + IsTruncated bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsTruncated"` + Contents []ListEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Contents,omitempty"` + CommonPrefixes []PrefixEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CommonPrefixes,omitempty"` +} + +type ListEntry struct { + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` + Size int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Size"` + Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner,omitempty"` + StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass"` +} + +func (t *ListEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T ListEntry + var layout struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + layout.T = (*T)(t) + layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) + return e.EncodeElement(layout, start) +} +func (t *ListEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T ListEntry + var overlay struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + overlay.T = (*T)(t) + overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) + return d.DecodeElement(&overlay, &start) +} + +type ListVersionsResponse struct { + ListVersionsResponse ListVersionsResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListVersionsResponse"` +} + +type ListVersionsResult struct { + Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"` + Name string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Name"` + Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"` + KeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ KeyMarker"` + VersionIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersionIdMarker"` + NextKeyMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextKeyMarker,omitempty"` + NextVersionIdMarker string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ NextVersionIdMarker,omitempty"` + MaxKeys int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MaxKeys"` + Delimiter string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Delimiter,omitempty"` + IsTruncated bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsTruncated"` + Version VersionEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Version"` + DeleteMarker DeleteMarkerEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ DeleteMarker"` + CommonPrefixes []PrefixEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CommonPrefixes,omitempty"` +} + +type LoggingSettings struct { + TargetBucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TargetBucket"` + TargetPrefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TargetPrefix"` + TargetGrants AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TargetGrants,omitempty"` +} + +// May be one of COPY, REPLACE +type MetadataDirective string + +type MetadataEntry struct { + Name string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Name"` + Value string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Value"` +} + +// May be one of Enabled, Disabled +type MfaDeleteStatus string + +type NotificationConfiguration struct { + TopicConfiguration []TopicConfiguration `xml:"http://s3.amazonaws.com/doc/2006-03-01/ TopicConfiguration,omitempty"` +} + +// May be one of BucketOwner, Requester +type Payer string + +// May be one of READ, WRITE, READ_ACP, WRITE_ACP, FULL_CONTROL +type Permission string + +type PostResponse struct { + Location string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Location"` + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` +} + +type PrefixEntry struct { + Prefix string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Prefix"` +} + +type PutObject struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"` + ContentLength int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentLength"` + AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,omitempty"` + StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass,omitempty"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *PutObject) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T PutObject + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *PutObject) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T PutObject + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type PutObjectInline struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + Metadata []MetadataEntry `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Metadata,omitempty"` + Data []byte `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data"` + ContentLength int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ContentLength"` + AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,omitempty"` + StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass,omitempty"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *PutObjectInline) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T PutObjectInline + var layout struct { + *T + Data *xsdBase64Binary `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data"` + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Data = (*xsdBase64Binary)(&layout.T.Data) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *PutObjectInline) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T PutObjectInline + var overlay struct { + *T + Data *xsdBase64Binary `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Data"` + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Data = (*xsdBase64Binary)(&overlay.T.Data) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type PutObjectInlineResponse struct { + PutObjectInlineResponse PutObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PutObjectInlineResponse"` +} + +type PutObjectResponse struct { + PutObjectResponse PutObjectResult `xml:"http://s3.amazonaws.com/doc/2006-03-01/ PutObjectResponse"` +} + +type PutObjectResult struct { + ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` + LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` +} + +func (t *PutObjectResult) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T PutObjectResult + var layout struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + layout.T = (*T)(t) + layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) + return e.EncodeElement(layout, start) +} +func (t *PutObjectResult) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T PutObjectResult + var overlay struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + overlay.T = (*T)(t) + overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) + return d.DecodeElement(&overlay, &start) +} + +type RequestPaymentConfiguration struct { + Payer Payer `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Payer"` +} + +type Result struct { + Status Status `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Status"` +} + +type SetBucketAccessControlPolicy struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList,omitempty"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *SetBucketAccessControlPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T SetBucketAccessControlPolicy + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *SetBucketAccessControlPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T SetBucketAccessControlPolicy + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type SetBucketAccessControlPolicyResponse struct { +} + +type SetBucketLoggingStatus struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` + BucketLoggingStatus BucketLoggingStatus `xml:"http://s3.amazonaws.com/doc/2006-03-01/ BucketLoggingStatus"` +} + +func (t *SetBucketLoggingStatus) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T SetBucketLoggingStatus + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *SetBucketLoggingStatus) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T SetBucketLoggingStatus + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type SetBucketLoggingStatusResponse struct { +} + +type SetObjectAccessControlPolicy struct { + Bucket string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Bucket"` + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + AccessControlList AccessControlList `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AccessControlList"` + AWSAccessKeyId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ AWSAccessKeyId,omitempty"` + Timestamp time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + Signature string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Signature,omitempty"` + Credential string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Credential,omitempty"` +} + +func (t *SetObjectAccessControlPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T SetObjectAccessControlPolicy + var layout struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + layout.T = (*T)(t) + layout.Timestamp = (*xsdDateTime)(&layout.T.Timestamp) + return e.EncodeElement(layout, start) +} +func (t *SetObjectAccessControlPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T SetObjectAccessControlPolicy + var overlay struct { + *T + Timestamp *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Timestamp,omitempty"` + } + overlay.T = (*T)(t) + overlay.Timestamp = (*xsdDateTime)(&overlay.T.Timestamp) + return d.DecodeElement(&overlay, &start) +} + +type SetObjectAccessControlPolicyResponse struct { +} + +type Status struct { + Code int `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Code"` + Description string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Description"` +} + +// May be one of STANDARD, REDUCED_REDUNDANCY, GLACIER, UNKNOWN +type StorageClass string + +type TopicConfiguration struct { + Topic string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Topic"` + Event []string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Event"` +} + +type User struct { +} + +type VersionEntry struct { + Key string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Key"` + VersionId string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ VersionId"` + IsLatest bool `xml:"http://s3.amazonaws.com/doc/2006-03-01/ IsLatest"` + LastModified time.Time `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + ETag string `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ETag"` + Size int64 `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Size"` + Owner CanonicalUser `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Owner,omitempty"` + StorageClass StorageClass `xml:"http://s3.amazonaws.com/doc/2006-03-01/ StorageClass"` +} + +func (t *VersionEntry) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + type T VersionEntry + var layout struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + layout.T = (*T)(t) + layout.LastModified = (*xsdDateTime)(&layout.T.LastModified) + return e.EncodeElement(layout, start) +} +func (t *VersionEntry) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type T VersionEntry + var overlay struct { + *T + LastModified *xsdDateTime `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LastModified"` + } + overlay.T = (*T)(t) + overlay.LastModified = (*xsdDateTime)(&overlay.T.LastModified) + return d.DecodeElement(&overlay, &start) +} + +type VersioningConfiguration struct { + Status VersioningStatus `xml:"http://s3.amazonaws.com/doc/2006-03-01/ Status,omitempty"` + MfaDelete MfaDeleteStatus `xml:"http://s3.amazonaws.com/doc/2006-03-01/ MfaDelete,omitempty"` +} + +// May be one of Enabled, Suspended +type VersioningStatus string + +type xsdBase64Binary []byte + +func (b *xsdBase64Binary) UnmarshalText(text []byte) (err error) { + *b, err = base64.StdEncoding.DecodeString(string(text)) + return +} +func (b xsdBase64Binary) MarshalText() ([]byte, error) { + var buf bytes.Buffer + enc := base64.NewEncoder(base64.StdEncoding, &buf) + enc.Write([]byte(b)) + enc.Close() + return buf.Bytes(), nil +} + +type xsdDateTime time.Time + +func (t *xsdDateTime) UnmarshalText(text []byte) error { + return _unmarshalTime(text, (*time.Time)(t), "2006-01-02T15:04:05.999999999") +} +func (t xsdDateTime) MarshalText() ([]byte, error) { + return []byte((time.Time)(t).Format("2006-01-02T15:04:05.999999999")), nil +} +func (t xsdDateTime) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if (time.Time)(t).IsZero() { + return nil + } + m, err := t.MarshalText() + if err != nil { + return err + } + return e.EncodeElement(m, start) +} +func (t xsdDateTime) MarshalXMLAttr(name xml.Name) (xml.Attr, error) { + if (time.Time)(t).IsZero() { + return xml.Attr{}, nil + } + m, err := t.MarshalText() + return xml.Attr{Name: name, Value: string(m)}, err +} +func _unmarshalTime(text []byte, t *time.Time, format string) (err error) { + s := string(bytes.TrimSpace(text)) + *t, err = time.Parse(format, s) + if _, ok := err.(*time.ParseError); ok { + *t, err = time.Parse(format+"Z07:00", s) + } + return err +} diff --git a/weed/server/filer_grpc_server.go b/weed/server/filer_grpc_server.go index 1ec5439a5..feedb905d 100644 --- a/weed/server/filer_grpc_server.go +++ b/weed/server/filer_grpc_server.go @@ -12,6 +12,7 @@ import ( "github.com/chrislusf/seaweedfs/weed/operation" "github.com/chrislusf/seaweedfs/weed/pb/filer_pb" "strconv" + "github.com/chrislusf/seaweedfs/weed/util" ) func (fs *FilerServer) LookupDirectoryEntry(ctx context.Context, req *filer_pb.LookupDirectoryEntryRequest) (*filer_pb.LookupDirectoryEntryResponse, error) { @@ -162,7 +163,7 @@ func (fs *FilerServer) UpdateEntry(ctx context.Context, req *filer_pb.UpdateEntr } func (fs *FilerServer) DeleteEntry(ctx context.Context, req *filer_pb.DeleteEntryRequest) (resp *filer_pb.DeleteEntryResponse, err error) { - err = fs.filer.DeleteEntryMetaAndData(filer2.FullPath(filepath.Join(req.Directory, req.Name)), req.IsDeleteData) + err = fs.filer.DeleteEntryMetaAndData(filer2.FullPath(filepath.Join(req.Directory, req.Name)), req.IsRecursive, req.IsDeleteData) return &filer_pb.DeleteEntryResponse{}, err } @@ -211,3 +212,12 @@ func (fs *FilerServer) AssignVolume(ctx context.Context, req *filer_pb.AssignVol PublicUrl: assignResult.PublicUrl, }, err } + +func (fs *FilerServer) DeleteCollection(ctx context.Context, req *filer_pb.DeleteCollectionRequest) (resp *filer_pb.DeleteCollectionResponse, err error) { + + for _, master := range fs.option.Masters { + _, err = util.Get(fmt.Sprintf("http://%s/col/delete?collection=%s", master, req.Collection)) + } + + return &filer_pb.DeleteCollectionResponse{}, err +} diff --git a/weed/server/filer_server_handlers_write.go b/weed/server/filer_server_handlers_write.go index ba7c17b79..a02fe04aa 100644 --- a/weed/server/filer_server_handlers_write.go +++ b/weed/server/filer_server_handlers_write.go @@ -27,9 +27,20 @@ type FilerPostResult struct { func (fs *FilerServer) queryFileInfoByPath(w http.ResponseWriter, r *http.Request, path string) (fileId, urlLocation string, err error) { var entry *filer2.Entry - if entry, err = fs.filer.FindEntry(filer2.FullPath(path)); err != nil { + entry, err = fs.filer.FindEntry(filer2.FullPath(path)) + if err == filer2.ErrNotFound { + return "", "", nil + } + + if err != nil { glog.V(0).Infoln("failing to find path in filer store", path, err.Error()) writeJsonError(w, r, http.StatusInternalServerError, err) + return + } + + if len(entry.Chunks) == 0 { + glog.V(1).Infof("empty entry: %s", path) + w.WriteHeader(http.StatusNoContent) } else { fileId = entry.Chunks[0].FileId urlLocation, err = operation.LookupFileId(fs.filer.GetMaster(), fileId) @@ -59,9 +70,10 @@ func (fs *FilerServer) assignNewFileInfo(w http.ResponseWriter, r *http.Request, DataCenter: "", } } + assignResult, ae := operation.Assign(fs.filer.GetMaster(), ar, altRequest) if ae != nil { - glog.V(0).Infoln("failing to assign a file id", ae.Error()) + glog.Errorf("failing to assign a file id: %v", ae) writeJsonError(w, r, http.StatusInternalServerError, ae) err = ae return @@ -91,20 +103,24 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) { return } - var fileId, urlLocation string - var err error - + /* + var path string if strings.HasPrefix(r.Header.Get("Content-Type"), "multipart/form-data; boundary=") { - fileId, urlLocation, err = fs.multipartUploadAnalyzer(w, r, replication, collection, dataCenter) - if err != nil { - return - } + path, err = fs.multipartUploadAnalyzer(w, r, replication, collection, dataCenter) } else { - fileId, urlLocation, err = fs.monolithicUploadAnalyzer(w, r, replication, collection, dataCenter) - if err != nil { - return - } + path, err = fs.monolithicUploadAnalyzer(w, r, replication, collection, dataCenter) } + */ + + fileId, urlLocation, err := fs.queryFileInfoByPath(w, r, r.URL.Path) + if fileId, urlLocation, err = fs.queryFileInfoByPath(w, r, r.URL.Path); err == nil && fileId == "" { + fileId, urlLocation, err = fs.assignNewFileInfo(w, r, replication, collection, dataCenter) + } + if err != nil || fileId == "" || urlLocation == "" { + return + } + + glog.V(0).Infof("request header %+v, urlLocation: %v", r.Header, urlLocation) u, _ := url.Parse(urlLocation) @@ -131,7 +147,7 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) { } resp, do_err := util.Do(request) if do_err != nil { - glog.V(0).Infoln("failing to connect to volume server", r.RequestURI, do_err.Error()) + glog.Errorf("failing to connect to volume server %s: %v, %+v", r.RequestURI, do_err, r.Method) writeJsonError(w, r, http.StatusInternalServerError, do_err) return } @@ -215,7 +231,7 @@ func (fs *FilerServer) PostHandler(w http.ResponseWriter, r *http.Request) { // curl -X DELETE http://localhost:8888/path/to func (fs *FilerServer) DeleteHandler(w http.ResponseWriter, r *http.Request) { - err := fs.filer.DeleteEntryMetaAndData(filer2.FullPath(r.URL.Path), true) + err := fs.filer.DeleteEntryMetaAndData(filer2.FullPath(r.URL.Path), false, true) if err != nil { glog.V(4).Infoln("deleting", r.URL.Path, ":", err.Error()) writeJsonError(w, r, http.StatusInternalServerError, err) diff --git a/weed/server/filer_server_handlers_write_monopart.go b/weed/server/filer_server_handlers_write_monopart.go index 777d5bc43..ccafbe5c1 100644 --- a/weed/server/filer_server_handlers_write_monopart.go +++ b/weed/server/filer_server_handlers_write_monopart.go @@ -73,15 +73,8 @@ func checkContentMD5(w http.ResponseWriter, r *http.Request) (err error) { return } -func (fs *FilerServer) monolithicUploadAnalyzer(w http.ResponseWriter, r *http.Request, replication, collection string, dataCenter string) (fileId, urlLocation string, err error) { - /* - Amazon S3 ref link:[http://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html] - There is a long way to provide a completely compatibility against all Amazon S3 API, I just made - a simple data stream adapter between S3 PUT API and seaweedfs's volume storage Write API - 1. The request url format should be http://$host:$port/$bucketName/$objectName - 2. bucketName will be mapped to seaweedfs's collection name - 3. You could customize and make your enhancement. - */ +func (fs *FilerServer) monolithicUploadAnalyzer(w http.ResponseWriter, r *http.Request, replication, collection string, dataCenter string) (path string, err error) { + lastPos := strings.LastIndex(r.URL.Path, "/") if lastPos == -1 || lastPos == 0 || lastPos == len(r.URL.Path)-1 { glog.V(0).Infof("URL Path [%s] is invalid, could not retrieve file name", r.URL.Path) @@ -99,13 +92,8 @@ func (fs *FilerServer) monolithicUploadAnalyzer(w http.ResponseWriter, r *http.R return } - secondPos := strings.Index(r.URL.Path[1:], "/") + 1 - collection = r.URL.Path[1:secondPos] - path := r.URL.Path + path = r.URL.Path - if fileId, urlLocation, err = fs.queryFileInfoByPath(w, r, path); err == nil && fileId == "" { - fileId, urlLocation, err = fs.assignNewFileInfo(w, r, replication, collection, dataCenter) - } return } diff --git a/weed/server/filer_server_handlers_write_multipart.go b/weed/server/filer_server_handlers_write_multipart.go index 056317750..302b58e70 100644 --- a/weed/server/filer_server_handlers_write_multipart.go +++ b/weed/server/filer_server_handlers_write_multipart.go @@ -1,39 +1,13 @@ package weed_server import ( - "bytes" - "io/ioutil" "net/http" - "strings" - - "github.com/chrislusf/seaweedfs/weed/glog" - "github.com/chrislusf/seaweedfs/weed/storage" ) -func (fs *FilerServer) multipartUploadAnalyzer(w http.ResponseWriter, r *http.Request, replication, collection string, dataCenter string) (fileId, urlLocation string, err error) { +func (fs *FilerServer) multipartUploadAnalyzer(w http.ResponseWriter, r *http.Request, replication, collection string, dataCenter string) (path string, err error) { //Default handle way for http multipart if r.Method == "PUT" { - buf, _ := ioutil.ReadAll(r.Body) - r.Body = ioutil.NopCloser(bytes.NewBuffer(buf)) - fileName, _, _, _, _, _, _, _, pe := storage.ParseUpload(r) - if pe != nil { - glog.V(0).Infoln("failing to parse post body", pe.Error()) - writeJsonError(w, r, http.StatusInternalServerError, pe) - err = pe - return - } - //reconstruct http request body for following new request to volume server - r.Body = ioutil.NopCloser(bytes.NewBuffer(buf)) - - path := r.URL.Path - if strings.HasSuffix(path, "/") { - if fileName != "" { - path += fileName - } - } - fileId, urlLocation, err = fs.queryFileInfoByPath(w, r, path) - } else { - fileId, urlLocation, err = fs.assignNewFileInfo(w, r, replication, collection, dataCenter) + path = r.URL.Path } return } |
