[#73] Uploader, downloader structures refactoring
All checks were successful
/ Vulncheck (pull_request) Successful in 1m32s
/ Lint (pull_request) Successful in 2m28s
/ Tests (1.20) (pull_request) Successful in 1m52s
/ Tests (1.21) (pull_request) Successful in 1m21s
/ DCO (pull_request) Successful in 3m25s
/ Builds (1.20) (pull_request) Successful in 5m38s
/ Builds (1.21) (pull_request) Successful in 1m23s
All checks were successful
/ Vulncheck (pull_request) Successful in 1m32s
/ Lint (pull_request) Successful in 2m28s
/ Tests (1.20) (pull_request) Successful in 1m52s
/ Tests (1.21) (pull_request) Successful in 1m21s
/ DCO (pull_request) Successful in 3m25s
/ Builds (1.20) (pull_request) Successful in 5m38s
/ Builds (1.21) (pull_request) Successful in 1m23s
Signed-off-by: Marina Biryukova <m.biryukova@yadro.com>
This commit is contained in:
parent
add07a21ed
commit
d219943542
27 changed files with 672 additions and 664 deletions
122
internal/handler/head.go
Normal file
122
internal/handler/head.go
Normal file
|
@ -0,0 +1,122 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-http-gw/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-http-gw/utils"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
||||
"github.com/valyala/fasthttp"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// max bytes needed to detect content type according to http.DetectContentType docs.
|
||||
const sizeToDetectType = 512
|
||||
|
||||
const (
|
||||
hdrObjectID = "X-Object-Id"
|
||||
hdrOwnerID = "X-Owner-Id"
|
||||
hdrContainerID = "X-Container-Id"
|
||||
)
|
||||
|
||||
func (h *Handler) headObject(ctx context.Context, req request, objectAddress oid.Address) {
|
||||
var start = time.Now()
|
||||
|
||||
btoken := bearerToken(ctx)
|
||||
|
||||
var prm pool.PrmObjectHead
|
||||
prm.SetAddress(objectAddress)
|
||||
if btoken != nil {
|
||||
prm.UseBearer(*btoken)
|
||||
}
|
||||
|
||||
obj, err := h.pool.HeadObject(ctx, prm)
|
||||
if err != nil {
|
||||
req.handleFrostFSErr(err, start)
|
||||
return
|
||||
}
|
||||
|
||||
req.Response.Header.Set(fasthttp.HeaderContentLength, strconv.FormatUint(obj.PayloadSize(), 10))
|
||||
var contentType string
|
||||
for _, attr := range obj.Attributes() {
|
||||
key := attr.Key()
|
||||
val := attr.Value()
|
||||
if !isValidToken(key) || !isValidValue(val) {
|
||||
continue
|
||||
}
|
||||
|
||||
key = utils.BackwardTransformIfSystem(key)
|
||||
|
||||
req.Response.Header.Set(utils.UserAttributeHeaderPrefix+key, val)
|
||||
switch key {
|
||||
case object.AttributeTimestamp:
|
||||
value, err := strconv.ParseInt(val, 10, 64)
|
||||
if err != nil {
|
||||
req.log.Info(logs.CouldntParseCreationDate,
|
||||
zap.String("key", key),
|
||||
zap.String("val", val),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
req.Response.Header.Set(fasthttp.HeaderLastModified, time.Unix(value, 0).UTC().Format(http.TimeFormat))
|
||||
case object.AttributeContentType:
|
||||
contentType = val
|
||||
}
|
||||
}
|
||||
|
||||
idsToResponse(&req.Response, &obj)
|
||||
|
||||
if len(contentType) == 0 {
|
||||
contentType, _, err = readContentType(obj.PayloadSize(), func(sz uint64) (io.Reader, error) {
|
||||
var prmRange pool.PrmObjectRange
|
||||
prmRange.SetAddress(objectAddress)
|
||||
prmRange.SetLength(sz)
|
||||
if btoken != nil {
|
||||
prmRange.UseBearer(*btoken)
|
||||
}
|
||||
|
||||
resObj, err := h.pool.ObjectRange(ctx, prmRange)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resObj, nil
|
||||
})
|
||||
if err != nil && err != io.EOF {
|
||||
req.handleFrostFSErr(err, start)
|
||||
return
|
||||
}
|
||||
}
|
||||
req.SetContentType(contentType)
|
||||
}
|
||||
|
||||
func idsToResponse(resp *fasthttp.Response, obj *object.Object) {
|
||||
objID, _ := obj.ID()
|
||||
cnrID, _ := obj.ContainerID()
|
||||
resp.Header.Set(hdrObjectID, objID.String())
|
||||
resp.Header.Set(hdrOwnerID, obj.OwnerID().String())
|
||||
resp.Header.Set(hdrContainerID, cnrID.String())
|
||||
}
|
||||
|
||||
// HeadByAddressOrBucketName handles head requests using simple cid/oid or bucketname/key format.
|
||||
func (h *Handler) HeadByAddressOrBucketName(c *fasthttp.RequestCtx) {
|
||||
test, _ := c.UserValue("oid").(string)
|
||||
var id oid.ID
|
||||
|
||||
err := id.DecodeString(test)
|
||||
if err != nil {
|
||||
h.byBucketname(c, h.headObject)
|
||||
} else {
|
||||
h.byAddress(c, h.headObject)
|
||||
}
|
||||
}
|
||||
|
||||
// HeadByAttribute handles attribute-based head requests.
|
||||
func (h *Handler) HeadByAttribute(c *fasthttp.RequestCtx) {
|
||||
h.byAttribute(c, h.headObject)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue