forked from TrueCloudLab/frostfs-rest-gw
[#1] Use body to provide object attribute
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
3727f5561d
commit
06060348ae
8 changed files with 285 additions and 164 deletions
|
@ -227,13 +227,17 @@ func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnr
|
||||||
attrKey: attrValue,
|
attrKey: attrValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
req := operations.PutObjectBody{
|
req := &models.ObjectUpload{
|
||||||
ContainerID: handlers.NewString(cnrID.String()),
|
ContainerID: handlers.NewString(cnrID.String()),
|
||||||
FileName: handlers.NewString("newFile.txt"),
|
FileName: handlers.NewString("newFile.txt"),
|
||||||
Payload: base64.StdEncoding.EncodeToString([]byte(content)),
|
Payload: base64.StdEncoding.EncodeToString([]byte(content)),
|
||||||
|
Attributes: []*models.Attribute{{
|
||||||
|
Key: &attrKey,
|
||||||
|
Value: &attrValue,
|
||||||
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := json.Marshal(&req)
|
body, err := json.Marshal(req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
|
@ -242,7 +246,6 @@ func restObjectPut(ctx context.Context, t *testing.T, clientPool *pool.Pool, cnr
|
||||||
request, err := http.NewRequest(http.MethodPut, testHost+"/v1/objects?"+query.Encode(), bytes.NewReader(body))
|
request, err := http.NewRequest(http.MethodPut, testHost+"/v1/objects?"+query.Encode(), bytes.NewReader(body))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
prepareCommonHeaders(request.Header, bearerToken)
|
prepareCommonHeaders(request.Header, bearerToken)
|
||||||
request.Header.Add("X-Attribute-"+attrKey, attrValue)
|
|
||||||
|
|
||||||
addr := &models.Address{}
|
addr := &models.Address{}
|
||||||
doRequest(t, httpClient, request, http.StatusOK, addr)
|
doRequest(t, httpClient, request, http.StatusOK, addr)
|
||||||
|
|
155
gen/models/object_upload.go
Normal file
155
gen/models/object_upload.go
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
// Code generated by go-swagger; DO NOT EDIT.
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
"github.com/go-openapi/swag"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ObjectUpload object upload
|
||||||
|
// Example: {"attributes":[{"key":"User-Attribute","value":"some-value"}],"containerId":"5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv","fileName":"myFile.txt","payload":"Y29udGVudCBvZiBmaWxl"}
|
||||||
|
//
|
||||||
|
// swagger:model ObjectUpload
|
||||||
|
type ObjectUpload struct {
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
Attributes []*Attribute `json:"attributes"`
|
||||||
|
|
||||||
|
// container Id
|
||||||
|
// Required: true
|
||||||
|
ContainerID *string `json:"containerId"`
|
||||||
|
|
||||||
|
// file name
|
||||||
|
// Required: true
|
||||||
|
FileName *string `json:"fileName"`
|
||||||
|
|
||||||
|
// payload
|
||||||
|
Payload string `json:"payload,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates this object upload
|
||||||
|
func (m *ObjectUpload) Validate(formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.validateAttributes(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateContainerID(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.validateFileName(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectUpload) validateAttributes(formats strfmt.Registry) error {
|
||||||
|
if swag.IsZero(m.Attributes) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(m.Attributes); i++ {
|
||||||
|
if swag.IsZero(m.Attributes[i]) { // not required
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Attributes[i] != nil {
|
||||||
|
if err := m.Attributes[i].Validate(formats); err != nil {
|
||||||
|
if ve, ok := err.(*errors.Validation); ok {
|
||||||
|
return ve.ValidateName("attributes" + "." + strconv.Itoa(i))
|
||||||
|
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||||
|
return ce.ValidateName("attributes" + "." + strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectUpload) validateContainerID(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("containerId", "body", m.ContainerID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectUpload) validateFileName(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("fileName", "body", m.FileName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextValidate validate this object upload based on the context it is used
|
||||||
|
func (m *ObjectUpload) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.contextValidateAttributes(ctx, formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ObjectUpload) contextValidateAttributes(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
for i := 0; i < len(m.Attributes); i++ {
|
||||||
|
|
||||||
|
if m.Attributes[i] != nil {
|
||||||
|
if err := m.Attributes[i].ContextValidate(ctx, formats); err != nil {
|
||||||
|
if ve, ok := err.(*errors.Validation); ok {
|
||||||
|
return ve.ValidateName("attributes" + "." + strconv.Itoa(i))
|
||||||
|
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||||
|
return ce.ValidateName("attributes" + "." + strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary interface implementation
|
||||||
|
func (m *ObjectUpload) MarshalBinary() ([]byte, error) {
|
||||||
|
if m == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return swag.WriteJSON(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary interface implementation
|
||||||
|
func (m *ObjectUpload) UnmarshalBinary(b []byte) error {
|
||||||
|
var res ObjectUpload
|
||||||
|
if err := swag.ReadJSON(b, &res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m = res
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -340,27 +340,7 @@ func init() {
|
||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"$ref": "#/definitions/ObjectUpload"
|
||||||
"required": [
|
|
||||||
"containerId",
|
|
||||||
"fileName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"containerId": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fileName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"example": {
|
|
||||||
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
|
||||||
"fileName": "myFile.txt",
|
|
||||||
"payload": "Y29udGVudCBvZiBmaWxl"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -817,6 +797,41 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ObjectUpload": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"containerId",
|
||||||
|
"fileName"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"attributes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Attribute"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fileName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"key": "User-Attribute",
|
||||||
|
"value": "some-value"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"fileName": "myFile.txt",
|
||||||
|
"payload": "Y29udGVudCBvZiBmaWxl"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Operation": {
|
"Operation": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
@ -1424,27 +1439,7 @@ func init() {
|
||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"$ref": "#/definitions/ObjectUpload"
|
||||||
"required": [
|
|
||||||
"containerId",
|
|
||||||
"fileName"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"containerId": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"fileName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"example": {
|
|
||||||
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
|
||||||
"fileName": "myFile.txt",
|
|
||||||
"payload": "Y29udGVudCBvZiBmaWxl"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -1952,6 +1947,41 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ObjectUpload": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"containerId",
|
||||||
|
"fileName"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"attributes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Attribute"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerId": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fileName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"key": "User-Attribute",
|
||||||
|
"value": "some-value"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"containerId": "5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv",
|
||||||
|
"fileName": "myFile.txt",
|
||||||
|
"payload": "Y29udGVudCBvZiBmaWxl"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Operation": {
|
"Operation": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
|
|
@ -6,14 +6,9 @@ package operations
|
||||||
// Editing this file might prove futile when you re-run the generate command
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-openapi/errors"
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/strfmt"
|
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/go-openapi/validate"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||||
)
|
)
|
||||||
|
@ -74,80 +69,3 @@ func (o *PutObject) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutObjectBody put object body
|
|
||||||
// Example: {"containerId":"5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv","fileName":"myFile.txt","payload":"Y29udGVudCBvZiBmaWxl"}
|
|
||||||
//
|
|
||||||
// swagger:model PutObjectBody
|
|
||||||
type PutObjectBody struct {
|
|
||||||
|
|
||||||
// container Id
|
|
||||||
// Required: true
|
|
||||||
ContainerID *string `json:"containerId"`
|
|
||||||
|
|
||||||
// file name
|
|
||||||
// Required: true
|
|
||||||
FileName *string `json:"fileName"`
|
|
||||||
|
|
||||||
// payload
|
|
||||||
Payload string `json:"payload,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate validates this put object body
|
|
||||||
func (o *PutObjectBody) Validate(formats strfmt.Registry) error {
|
|
||||||
var res []error
|
|
||||||
|
|
||||||
if err := o.validateContainerID(formats); err != nil {
|
|
||||||
res = append(res, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := o.validateFileName(formats); err != nil {
|
|
||||||
res = append(res, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(res) > 0 {
|
|
||||||
return errors.CompositeValidationError(res...)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *PutObjectBody) validateContainerID(formats strfmt.Registry) error {
|
|
||||||
|
|
||||||
if err := validate.Required("object"+"."+"containerId", "body", o.ContainerID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *PutObjectBody) validateFileName(formats strfmt.Registry) error {
|
|
||||||
|
|
||||||
if err := validate.Required("object"+"."+"fileName", "body", o.FileName); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContextValidate validates this put object body based on context it is used
|
|
||||||
func (o *PutObjectBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalBinary interface implementation
|
|
||||||
func (o *PutObjectBody) MarshalBinary() ([]byte, error) {
|
|
||||||
if o == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return swag.WriteJSON(o)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalBinary interface implementation
|
|
||||||
func (o *PutObjectBody) UnmarshalBinary(b []byte) error {
|
|
||||||
var res PutObjectBody
|
|
||||||
if err := swag.ReadJSON(b, &res); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*o = res
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ import (
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/go-openapi/swag"
|
"github.com/go-openapi/swag"
|
||||||
"github.com/go-openapi/validate"
|
"github.com/go-openapi/validate"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewPutObjectParams creates a new PutObjectParams object
|
// NewPutObjectParams creates a new PutObjectParams object
|
||||||
|
@ -56,7 +58,7 @@ type PutObjectParams struct {
|
||||||
Required: true
|
Required: true
|
||||||
In: body
|
In: body
|
||||||
*/
|
*/
|
||||||
Object PutObjectBody
|
Object *models.ObjectUpload
|
||||||
/*Use wallect connect signature scheme or not
|
/*Use wallect connect signature scheme or not
|
||||||
In: query
|
In: query
|
||||||
Default: false
|
Default: false
|
||||||
|
@ -85,7 +87,7 @@ func (o *PutObjectParams) BindRequest(r *http.Request, route *middleware.Matched
|
||||||
|
|
||||||
if runtime.HasBody(r) {
|
if runtime.HasBody(r) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
var body PutObjectBody
|
var body models.ObjectUpload
|
||||||
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
res = append(res, errors.Required("object", "body", ""))
|
res = append(res, errors.Required("object", "body", ""))
|
||||||
|
@ -104,7 +106,7 @@ func (o *PutObjectParams) BindRequest(r *http.Request, route *middleware.Matched
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(res) == 0 {
|
if len(res) == 0 {
|
||||||
o.Object = body
|
o.Object = &body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,6 +5,9 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
||||||
|
@ -19,8 +22,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/pool"
|
"github.com/nspcc-dev/neofs-sdk-go/pool"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/token"
|
"github.com/nspcc-dev/neofs-sdk-go/token"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PutObjects handler that uploads object to NeoFS.
|
// PutObjects handler that uploads object to NeoFS.
|
||||||
|
@ -48,7 +49,7 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
|
||||||
DefaultTimestamp: a.defaultTimestamp,
|
DefaultTimestamp: a.defaultTimestamp,
|
||||||
DefaultFileName: *params.Object.FileName,
|
DefaultFileName: *params.Object.FileName,
|
||||||
}
|
}
|
||||||
attributes, err := GetObjectAttributes(ctx, params.HTTPRequest.Header, a.pool, prm)
|
attributes, err := GetObjectAttributes(ctx, a.pool, params.Object.Attributes, prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorResponse.WithPayload(models.Error(err.Error()))
|
return errorResponse.WithPayload(models.Error(err.Error()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,35 +87,38 @@ func filterHeaders(header http.Header) map[string]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjectAttributes forms object attributes from request headers.
|
// GetObjectAttributes forms object attributes from request headers.
|
||||||
func GetObjectAttributes(ctx context.Context, header http.Header, pool *pool.Pool, prm PrmAttributes) ([]object.Attribute, error) {
|
func GetObjectAttributes(ctx context.Context, pool *pool.Pool, attrs []*models.Attribute, prm PrmAttributes) ([]object.Attribute, error) {
|
||||||
filtered := filterHeaders(header)
|
headers := make(map[string]string, len(attrs))
|
||||||
if needParseExpiration(filtered) {
|
|
||||||
|
for _, attr := range attrs {
|
||||||
|
headers[*attr.Key] = *attr.Value
|
||||||
|
}
|
||||||
|
delete(headers, object.AttributeFileName)
|
||||||
|
|
||||||
|
if needParseExpiration(headers) {
|
||||||
epochDuration, err := getEpochDurations(ctx, pool)
|
epochDuration, err := getEpochDurations(ctx, pool)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not get epoch durations from network info: %w", err)
|
return nil, fmt.Errorf("could not get epoch durations from network info: %w", err)
|
||||||
}
|
}
|
||||||
if err = prepareExpirationHeader(filtered, epochDuration); err != nil {
|
if err = prepareExpirationHeader(headers, epochDuration); err != nil {
|
||||||
return nil, fmt.Errorf("could not prepare expiration header: %w", err)
|
return nil, fmt.Errorf("could not prepare expiration header: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes := make([]object.Attribute, 0, len(filtered))
|
attributes := make([]object.Attribute, 0, len(headers))
|
||||||
// prepares attributes from filtered headers
|
for key, val := range headers {
|
||||||
for key, val := range filtered {
|
|
||||||
attribute := object.NewAttribute()
|
attribute := object.NewAttribute()
|
||||||
attribute.SetKey(key)
|
attribute.SetKey(key)
|
||||||
attribute.SetValue(val)
|
attribute.SetValue(val)
|
||||||
attributes = append(attributes, *attribute)
|
attributes = append(attributes, *attribute)
|
||||||
}
|
}
|
||||||
// sets FileName attribute if it wasn't set from header
|
|
||||||
if _, ok := filtered[object.AttributeFileName]; !ok && prm.DefaultFileName != "" {
|
|
||||||
filename := object.NewAttribute()
|
filename := object.NewAttribute()
|
||||||
filename.SetKey(object.AttributeFileName)
|
filename.SetKey(object.AttributeFileName)
|
||||||
filename.SetValue(prm.DefaultFileName)
|
filename.SetValue(prm.DefaultFileName)
|
||||||
attributes = append(attributes, *filename)
|
attributes = append(attributes, *filename)
|
||||||
}
|
|
||||||
// sets Timestamp attribute if it wasn't set from header and enabled by settings
|
if _, ok := headers[object.AttributeTimestamp]; !ok && prm.DefaultTimestamp {
|
||||||
if _, ok := filtered[object.AttributeTimestamp]; !ok && prm.DefaultTimestamp {
|
|
||||||
timestamp := object.NewAttribute()
|
timestamp := object.NewAttribute()
|
||||||
timestamp.SetKey(object.AttributeTimestamp)
|
timestamp.SetKey(object.AttributeTimestamp)
|
||||||
timestamp.SetValue(strconv.FormatInt(time.Now().Unix(), 10))
|
timestamp.SetValue(strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
|
|
|
@ -107,21 +107,7 @@ paths:
|
||||||
name: object
|
name: object
|
||||||
description: Object info to upload
|
description: Object info to upload
|
||||||
schema:
|
schema:
|
||||||
type: object
|
$ref: '#/definitions/ObjectUpload'
|
||||||
properties:
|
|
||||||
containerId:
|
|
||||||
type: string
|
|
||||||
fileName:
|
|
||||||
type: string
|
|
||||||
payload:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- containerId
|
|
||||||
- fileName
|
|
||||||
example:
|
|
||||||
containerId: 5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv
|
|
||||||
fileName: myFile.txt
|
|
||||||
payload: Y29udGVudCBvZiBmaWxl
|
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
produces:
|
produces:
|
||||||
|
@ -618,6 +604,29 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
- address
|
- address
|
||||||
|
ObjectUpload:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
containerId:
|
||||||
|
type: string
|
||||||
|
fileName:
|
||||||
|
type: string
|
||||||
|
payload:
|
||||||
|
type: string
|
||||||
|
attributes:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/Attribute'
|
||||||
|
required:
|
||||||
|
- containerId
|
||||||
|
- fileName
|
||||||
|
example:
|
||||||
|
containerId: 5HZTn5qkRnmgSz9gSrw22CEdPPk6nQhkwf2Mgzyvkikv
|
||||||
|
fileName: myFile.txt
|
||||||
|
payload: Y29udGVudCBvZiBmaWxl
|
||||||
|
attributes:
|
||||||
|
- key: User-Attribute
|
||||||
|
value: some-value
|
||||||
ObjectInfo:
|
ObjectInfo:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|
Loading…
Reference in a new issue