forked from TrueCloudLab/frostfs-s3-gw
[#657] Replace FileName with FilePath attribute
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
c051d21420
commit
9cd4ef1ac4
13 changed files with 37 additions and 37 deletions
2
api/cache/system.go
vendored
2
api/cache/system.go
vendored
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
// SystemCache provides lru cache for objects.
|
// SystemCache provides lru cache for objects.
|
||||||
// This cache contains "system" objects (bucket versioning settings, tagging object etc.).
|
// This cache contains "system" objects (bucket versioning settings, tagging object etc.).
|
||||||
// Key is bucketName+systemFileName.
|
// Key is bucketName+systemFilePath.
|
||||||
type SystemCache struct {
|
type SystemCache struct {
|
||||||
cache gcache.Cache
|
cache gcache.Cache
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
|
|
|
@ -675,7 +675,7 @@ func resInfoFromFilters(bucketName string, filters []eacl.Filter) resourceInfo {
|
||||||
resInfo := resourceInfo{Bucket: bucketName}
|
resInfo := resourceInfo{Bucket: bucketName}
|
||||||
for _, filter := range filters {
|
for _, filter := range filters {
|
||||||
if filter.Matcher() == eacl.MatchStringEqual {
|
if filter.Matcher() == eacl.MatchStringEqual {
|
||||||
if filter.Key() == object.AttributeFileName {
|
if filter.Key() == object.AttributeFilePath {
|
||||||
resInfo.Object = filter.Value()
|
resInfo.Object = filter.Value()
|
||||||
} else if filter.Key() == v2acl.FilterObjectID {
|
} else if filter.Key() == v2acl.FilterObjectID {
|
||||||
resInfo.Version = filter.Value()
|
resInfo.Version = filter.Value()
|
||||||
|
@ -938,7 +938,7 @@ func formRecords(resource *astResource) ([]*eacl.Record, error) {
|
||||||
}
|
}
|
||||||
record.AddObjectIDFilter(eacl.MatchStringEqual, id)
|
record.AddObjectIDFilter(eacl.MatchStringEqual, id)
|
||||||
} else {
|
} else {
|
||||||
record.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFileName, resource.Object)
|
record.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFilePath, resource.Object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = append(res, record)
|
res = append(res, record)
|
||||||
|
|
|
@ -41,7 +41,7 @@ func TestTableToAst(t *testing.T) {
|
||||||
record2.SetOperation(eacl.OperationPut)
|
record2.SetOperation(eacl.OperationPut)
|
||||||
// Unknown role is used, because it is ignored when keys are set
|
// Unknown role is used, because it is ignored when keys are set
|
||||||
eacl.AddFormedTarget(record2, eacl.RoleUnknown, *(*ecdsa.PublicKey)(key.PublicKey()), *((*ecdsa.PublicKey)(key2.PublicKey())))
|
eacl.AddFormedTarget(record2, eacl.RoleUnknown, *(*ecdsa.PublicKey)(key.PublicKey()), *((*ecdsa.PublicKey)(key2.PublicKey())))
|
||||||
record2.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFileName, "objectName")
|
record2.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFilePath, "objectName")
|
||||||
record2.AddObjectIDFilter(eacl.MatchStringEqual, id)
|
record2.AddObjectIDFilter(eacl.MatchStringEqual, id)
|
||||||
table.AddRecord(record2)
|
table.AddRecord(record2)
|
||||||
|
|
||||||
|
@ -480,12 +480,12 @@ func TestOrder(t *testing.T) {
|
||||||
objectUsersPutRec := eacl.NewRecord()
|
objectUsersPutRec := eacl.NewRecord()
|
||||||
objectUsersPutRec.SetOperation(eacl.OperationPut)
|
objectUsersPutRec.SetOperation(eacl.OperationPut)
|
||||||
objectUsersPutRec.SetAction(eacl.ActionAllow)
|
objectUsersPutRec.SetAction(eacl.ActionAllow)
|
||||||
objectUsersPutRec.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFileName, objectName)
|
objectUsersPutRec.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFilePath, objectName)
|
||||||
objectUsersPutRec.SetTargets(*targetUser)
|
objectUsersPutRec.SetTargets(*targetUser)
|
||||||
objectOtherPutRec := eacl.NewRecord()
|
objectOtherPutRec := eacl.NewRecord()
|
||||||
objectOtherPutRec.SetOperation(eacl.OperationPut)
|
objectOtherPutRec.SetOperation(eacl.OperationPut)
|
||||||
objectOtherPutRec.SetAction(eacl.ActionDeny)
|
objectOtherPutRec.SetAction(eacl.ActionDeny)
|
||||||
objectOtherPutRec.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFileName, objectName)
|
objectOtherPutRec.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFilePath, objectName)
|
||||||
objectOtherPutRec.SetTargets(*targetOther)
|
objectOtherPutRec.SetTargets(*targetOther)
|
||||||
|
|
||||||
expectedEacl := eacl.NewTable()
|
expectedEacl := eacl.NewTable()
|
||||||
|
@ -528,7 +528,7 @@ func TestOrder(t *testing.T) {
|
||||||
childRecord.SetOperation(eacl.OperationDelete)
|
childRecord.SetOperation(eacl.OperationDelete)
|
||||||
childRecord.SetAction(eacl.ActionDeny)
|
childRecord.SetAction(eacl.ActionDeny)
|
||||||
childRecord.SetTargets(*targetOther)
|
childRecord.SetTargets(*targetOther)
|
||||||
childRecord.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFileName, childName)
|
childRecord.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFilePath, childName)
|
||||||
|
|
||||||
mergedAst, updated := mergeAst(expectedAst, child)
|
mergedAst, updated := mergeAst(expectedAst, child)
|
||||||
require.True(t, updated)
|
require.True(t, updated)
|
||||||
|
@ -654,7 +654,7 @@ func TestAstToTable(t *testing.T) {
|
||||||
record2.SetAction(eacl.ActionDeny)
|
record2.SetAction(eacl.ActionDeny)
|
||||||
record2.SetOperation(eacl.OperationGet)
|
record2.SetOperation(eacl.OperationGet)
|
||||||
eacl.AddFormedTarget(record2, eacl.RoleOthers)
|
eacl.AddFormedTarget(record2, eacl.RoleOthers)
|
||||||
record2.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFileName, "objectName")
|
record2.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFilePath, "objectName")
|
||||||
|
|
||||||
expectedTable.AddRecord(serviceRec2.ToEACLRecord())
|
expectedTable.AddRecord(serviceRec2.ToEACLRecord())
|
||||||
expectedTable.AddRecord(record2)
|
expectedTable.AddRecord(record2)
|
||||||
|
@ -895,7 +895,7 @@ func allowedTableForPrivateObject(t *testing.T, key *keys.PrivateKey, resInfo *r
|
||||||
if isVersion {
|
if isVersion {
|
||||||
record.AddObjectIDFilter(eacl.MatchStringEqual, objID)
|
record.AddObjectIDFilter(eacl.MatchStringEqual, objID)
|
||||||
} else {
|
} else {
|
||||||
record.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFileName, resInfo.Object)
|
record.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFilePath, resInfo.Object)
|
||||||
}
|
}
|
||||||
expectedTable.AddRecord(record)
|
expectedTable.AddRecord(record)
|
||||||
}
|
}
|
||||||
|
@ -905,7 +905,7 @@ func allowedTableForPrivateObject(t *testing.T, key *keys.PrivateKey, resInfo *r
|
||||||
if isVersion {
|
if isVersion {
|
||||||
record.AddObjectIDFilter(eacl.MatchStringEqual, objID)
|
record.AddObjectIDFilter(eacl.MatchStringEqual, objID)
|
||||||
} else {
|
} else {
|
||||||
record.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFileName, resInfo.Object)
|
record.AddObjectAttributeFilter(eacl.MatchStringEqual, object.AttributeFilePath, resInfo.Object)
|
||||||
}
|
}
|
||||||
expectedTable.AddRecord(record)
|
expectedTable.AddRecord(record)
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(info.ContentType) == 0 {
|
if len(info.ContentType) == 0 {
|
||||||
if info.ContentType = layer.MimeByFileName(info.Name); len(info.ContentType) == 0 {
|
if info.ContentType = layer.MimeByFilePath(info.Name); len(info.ContentType) == 0 {
|
||||||
buffer := bytes.NewBuffer(make([]byte, 0, sizeToDetectType))
|
buffer := bytes.NewBuffer(make([]byte, 0, sizeToDetectType))
|
||||||
getParams := &layer.GetObjectParams{
|
getParams := &layer.GetObjectParams{
|
||||||
ObjectInfo: info,
|
ObjectInfo: info,
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (n *layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error {
|
||||||
Container: p.BktInfo.CID,
|
Container: p.BktInfo.CID,
|
||||||
Creator: p.BktInfo.Owner,
|
Creator: p.BktInfo.Owner,
|
||||||
Payload: p.Reader,
|
Payload: p.Reader,
|
||||||
Filename: p.BktInfo.CORSObjectName(),
|
Filepath: p.BktInfo.CORSObjectName(),
|
||||||
CopiesNumber: p.CopiesNumber,
|
CopiesNumber: p.CopiesNumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func (n *layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.systemCache.PutCORS(systemObjectKey(p.BktInfo, prm.Filename), cors); err != nil {
|
if err = n.systemCache.PutCORS(systemObjectKey(p.BktInfo, prm.Filepath), cors); err != nil {
|
||||||
n.log.Error("couldn't cache system object", zap.Error(err))
|
n.log.Error("couldn't cache system object", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,8 @@ type PrmObjectCreate struct {
|
||||||
// Full payload size (optional).
|
// Full payload size (optional).
|
||||||
PayloadSize uint64
|
PayloadSize uint64
|
||||||
|
|
||||||
// Associated filename (optional).
|
// Associated filepath (optional).
|
||||||
Filename string
|
Filepath string
|
||||||
|
|
||||||
// Object payload encapsulated in io.Reader primitive.
|
// Object payload encapsulated in io.Reader primitive.
|
||||||
Payload io.Reader
|
Payload io.Reader
|
||||||
|
|
|
@ -157,10 +157,10 @@ func (t *TestNeoFS) CreateObject(_ context.Context, prm PrmObjectCreate) (oid.ID
|
||||||
|
|
||||||
attrs := make([]object.Attribute, 0)
|
attrs := make([]object.Attribute, 0)
|
||||||
|
|
||||||
if prm.Filename != "" {
|
if prm.Filepath != "" {
|
||||||
a := object.NewAttribute()
|
a := object.NewAttribute()
|
||||||
a.SetKey(object.AttributeFileName)
|
a.SetKey(object.AttributeFilePath)
|
||||||
a.SetValue(prm.Filename)
|
a.SetValue(prm.Filepath)
|
||||||
attrs = append(attrs, *a)
|
attrs = append(attrs, *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ func (n *layer) PutBucketNotificationConfiguration(ctx context.Context, p *PutBu
|
||||||
Container: p.BktInfo.CID,
|
Container: p.BktInfo.CID,
|
||||||
Creator: p.BktInfo.Owner,
|
Creator: p.BktInfo.Owner,
|
||||||
Payload: bytes.NewReader(confXML),
|
Payload: bytes.NewReader(confXML),
|
||||||
Filename: sysName,
|
Filepath: sysName,
|
||||||
CopiesNumber: p.CopiesNumber,
|
CopiesNumber: p.CopiesNumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,9 +138,9 @@ func (n *layer) objectGet(ctx context.Context, bktInfo *data.BucketInfo, objID o
|
||||||
return res.Head, nil
|
return res.Head, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MimeByFileName detect mime type by filename extension.
|
// MimeByFilePath detect mime type by file path extension.
|
||||||
func MimeByFileName(name string) string {
|
func MimeByFilePath(path string) string {
|
||||||
ext := filepath.Ext(name)
|
ext := filepath.Ext(path)
|
||||||
if len(ext) == 0 {
|
if len(ext) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.Object
|
||||||
|
|
||||||
if r != nil {
|
if r != nil {
|
||||||
if len(p.Header[api.ContentType]) == 0 {
|
if len(p.Header[api.ContentType]) == 0 {
|
||||||
if contentType := MimeByFileName(p.Object); len(contentType) == 0 {
|
if contentType := MimeByFilePath(p.Object); len(contentType) == 0 {
|
||||||
d := newDetector(r)
|
d := newDetector(r)
|
||||||
if contentType, err := d.Detect(); err == nil {
|
if contentType, err := d.Detect(); err == nil {
|
||||||
p.Header[api.ContentType] = contentType
|
p.Header[api.ContentType] = contentType
|
||||||
|
@ -232,7 +232,7 @@ func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.Object
|
||||||
Container: p.BktInfo.CID,
|
Container: p.BktInfo.CID,
|
||||||
Creator: own,
|
Creator: own,
|
||||||
PayloadSize: uint64(p.Size),
|
PayloadSize: uint64(p.Size),
|
||||||
Filename: p.Object,
|
Filepath: p.Object,
|
||||||
Payload: r,
|
Payload: r,
|
||||||
CopiesNumber: p.CopiesNumber,
|
CopiesNumber: p.CopiesNumber,
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ func objectInfoFromMeta(bkt *data.BucketInfo, meta *object.Object) *data.ObjectI
|
||||||
)
|
)
|
||||||
|
|
||||||
headers := userHeaders(meta.Attributes())
|
headers := userHeaders(meta.Attributes())
|
||||||
delete(headers, object.AttributeFileName)
|
delete(headers, object.AttributeFilePath)
|
||||||
if contentType, ok := headers[object.AttributeContentType]; ok {
|
if contentType, ok := headers[object.AttributeContentType]; ok {
|
||||||
mimeType = contentType
|
mimeType = contentType
|
||||||
delete(headers, object.AttributeContentType)
|
delete(headers, object.AttributeContentType)
|
||||||
|
@ -89,7 +89,7 @@ func objectInfoFromMeta(bkt *data.BucketInfo, meta *object.Object) *data.ObjectI
|
||||||
IsDir: false,
|
IsDir: false,
|
||||||
|
|
||||||
Bucket: bkt.Name,
|
Bucket: bkt.Name,
|
||||||
Name: filenameFromObject(meta),
|
Name: filepathFromObject(meta),
|
||||||
Created: creation,
|
Created: creation,
|
||||||
ContentType: mimeType,
|
ContentType: mimeType,
|
||||||
Headers: headers,
|
Headers: headers,
|
||||||
|
@ -121,9 +121,9 @@ func addEncryptionHeaders(meta map[string]string, enc encryption.Params) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func filenameFromObject(o *object.Object) string {
|
func filepathFromObject(o *object.Object) string {
|
||||||
for _, attr := range o.Attributes() {
|
for _, attr := range o.Attributes() {
|
||||||
if attr.Key() == object.AttributeFileName {
|
if attr.Key() == object.AttributeFilePath {
|
||||||
return attr.Value()
|
return attr.Value()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ type PrmObjectCreate struct {
|
||||||
// NeoFS container to store the object.
|
// NeoFS container to store the object.
|
||||||
Container cid.ID
|
Container cid.ID
|
||||||
|
|
||||||
// File name.
|
// File path.
|
||||||
Filename string
|
Filepath string
|
||||||
|
|
||||||
// Last NeoFS epoch of the object lifetime.
|
// Last NeoFS epoch of the object lifetime.
|
||||||
ExpirationEpoch uint64
|
ExpirationEpoch uint64
|
||||||
|
@ -131,7 +131,7 @@ func (c *cred) Put(ctx context.Context, idCnr cid.ID, issuer user.ID, box *acces
|
||||||
idObj, err := c.neoFS.CreateObject(ctx, PrmObjectCreate{
|
idObj, err := c.neoFS.CreateObject(ctx, PrmObjectCreate{
|
||||||
Creator: issuer,
|
Creator: issuer,
|
||||||
Container: idCnr,
|
Container: idCnr,
|
||||||
Filename: strconv.FormatInt(time.Now().Unix(), 10) + "_access.box",
|
Filepath: strconv.FormatInt(time.Now().Unix(), 10) + "_access.box",
|
||||||
ExpirationEpoch: expiration,
|
ExpirationEpoch: expiration,
|
||||||
Payload: data,
|
Payload: data,
|
||||||
})
|
})
|
||||||
|
|
|
@ -66,7 +66,7 @@ To upload a file into a bucket in the NeoFS network, run the following command:
|
||||||
```
|
```
|
||||||
$ aws s3api put-object --bucket %BUCKET_NAME --key %OBJECT_KEY --body %FILEPATH
|
$ aws s3api put-object --bucket %BUCKET_NAME --key %OBJECT_KEY --body %FILEPATH
|
||||||
```
|
```
|
||||||
where %OBJECT_KEY is the filename of an object in NeoFS
|
where %OBJECT_KEY is the filepath of an object in NeoFS
|
||||||
|
|
||||||
#### Upload of a dir
|
#### Upload of a dir
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,7 @@ func (x *NeoFS) DeleteContainer(ctx context.Context, id cid.ID, token *session.C
|
||||||
func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oid.ID, error) {
|
func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oid.ID, error) {
|
||||||
attrNum := len(prm.Attributes) + 1 // + creation time
|
attrNum := len(prm.Attributes) + 1 // + creation time
|
||||||
|
|
||||||
if prm.Filename != "" {
|
if prm.Filepath != "" {
|
||||||
attrNum++
|
attrNum++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,10 +237,10 @@ func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oi
|
||||||
attrs = append(attrs, *a)
|
attrs = append(attrs, *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
if prm.Filename != "" {
|
if prm.Filepath != "" {
|
||||||
a = object.NewAttribute()
|
a = object.NewAttribute()
|
||||||
a.SetKey(object.AttributeFileName)
|
a.SetKey(object.AttributeFilePath)
|
||||||
a.SetValue(prm.Filename)
|
a.SetValue(prm.Filepath)
|
||||||
attrs = append(attrs, *a)
|
attrs = append(attrs, *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,7 +527,7 @@ func (x *AuthmateNeoFS) CreateObject(ctx context.Context, prm tokens.PrmObjectCr
|
||||||
return x.neoFS.CreateObject(ctx, layer.PrmObjectCreate{
|
return x.neoFS.CreateObject(ctx, layer.PrmObjectCreate{
|
||||||
Creator: prm.Creator,
|
Creator: prm.Creator,
|
||||||
Container: prm.Container,
|
Container: prm.Container,
|
||||||
Filename: prm.Filename,
|
Filepath: prm.Filepath,
|
||||||
Attributes: [][2]string{
|
Attributes: [][2]string{
|
||||||
{"__NEOFS__EXPIRATION_EPOCH", strconv.FormatUint(prm.ExpirationEpoch, 10)}},
|
{"__NEOFS__EXPIRATION_EPOCH", strconv.FormatUint(prm.ExpirationEpoch, 10)}},
|
||||||
Payload: bytes.NewReader(prm.Payload),
|
Payload: bytes.NewReader(prm.Payload),
|
||||||
|
|
Loading…
Reference in a new issue