diff --git a/api/handler/get.go b/api/handler/get.go index b2adadaa..9bce8ac3 100644 --- a/api/handler/get.go +++ b/api/handler/get.go @@ -1,8 +1,10 @@ package handler import ( + "io" "net/http" "strconv" + "sync" "github.com/gorilla/mux" "github.com/nspcc-dev/neofs-s3-gate/api" @@ -10,6 +12,31 @@ import ( "go.uber.org/zap" ) +type ( + detector struct { + io.Writer + sync.Once + + contentType string + } +) + +func newDetector(w io.Writer) *detector { + return &detector{Writer: w} +} + +func (d *detector) Write(data []byte) (int, error) { + d.Once.Do(func() { + if rw, ok := d.Writer.(http.ResponseWriter); ok { + rw.WriteHeader(http.StatusOK) + } + + d.contentType = http.DetectContentType(data) + }) + + return d.Writer.Write(data) +} + func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) { var ( err error @@ -37,10 +64,12 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) { return } + writer := newDetector(w) + params := &layer.GetObjectParams{ Bucket: inf.Bucket, Object: inf.Name, - Writer: w, + Writer: writer, } // params.Length = inf.Size @@ -61,9 +90,7 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) { return } - w.Header().Set("Content-Type", inf.ContentType) + w.Header().Set("Content-Type", writer.contentType) w.Header().Set("Last-Modified", inf.Created.Format(http.TimeFormat)) w.Header().Set("Content-Length", strconv.FormatInt(inf.Size, 10)) - - w.WriteHeader(http.StatusOK) }