diff --git a/api/handler/head.go b/api/handler/head.go index 2e11696be..f4bfaf4d2 100644 --- a/api/handler/head.go +++ b/api/handler/head.go @@ -69,18 +69,20 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { } if len(info.ContentType) == 0 { - buffer := bytes.NewBuffer(make([]byte, 0, sizeToDetectType)) - getParams := &layer.GetObjectParams{ - ObjectInfo: info, - Writer: buffer, - Range: getRangeToDetectContentType(info.Size), - BucketInfo: bktInfo, + if info.ContentType = layer.MimeByFileName(info.Name); len(info.ContentType) == 0 { + buffer := bytes.NewBuffer(make([]byte, 0, sizeToDetectType)) + getParams := &layer.GetObjectParams{ + ObjectInfo: info, + Writer: buffer, + Range: getRangeToDetectContentType(info.Size), + BucketInfo: bktInfo, + } + if err = h.obj.GetObject(r.Context(), getParams); err != nil { + h.logAndSendError(w, "could not get object", reqInfo, err, zap.Stringer("oid", info.ID)) + return + } + info.ContentType = http.DetectContentType(buffer.Bytes()) } - if err = h.obj.GetObject(r.Context(), getParams); err != nil { - h.logAndSendError(w, "could not get object", reqInfo, err, zap.Stringer("oid", info.ID)) - return - } - info.ContentType = http.DetectContentType(buffer.Bytes()) } if err = h.setLockingHeaders(r.Context(), bktInfo, info, w.Header()); err != nil { diff --git a/api/layer/object.go b/api/layer/object.go index b2e3bc165..f73206b2c 100644 --- a/api/layer/object.go +++ b/api/layer/object.go @@ -7,6 +7,8 @@ import ( "errors" "fmt" "io" + "mime" + "path/filepath" "sort" "strings" "time" @@ -155,6 +157,15 @@ func (n *layer) objectGet(ctx context.Context, bktInfo *data.BucketInfo, objID o return res.Head, nil } +// MimeByFileName detect mime type by filename extension. +func MimeByFileName(name string) string { + ext := filepath.Ext(name) + if len(ext) == 0 { + return "" + } + return mime.TypeByExtension(ext) +} + // PutObject stores object into NeoFS, took payload from io.Reader. func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.ObjectInfo, error) { own := n.Owner(ctx) @@ -169,11 +180,15 @@ func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.Object r := p.Reader if r != nil { if len(p.Header[api.ContentType]) == 0 { - d := newDetector(r) - if contentType, err := d.Detect(); err == nil { + if contentType := MimeByFileName(p.Object); len(contentType) == 0 { + d := newDetector(r) + if contentType, err = d.Detect(); err == nil { + p.Header[api.ContentType] = contentType + } + r = d.MultiReader() + } else { p.Header[api.ContentType] = contentType } - r = d.MultiReader() } }