diff --git a/api/handler/get.go b/api/handler/get.go index 0bfeb924f..1a910a009 100644 --- a/api/handler/get.go +++ b/api/handler/get.go @@ -3,6 +3,7 @@ package handler import ( "fmt" "net/http" + "net/url" "strconv" "strings" "time" @@ -66,8 +67,16 @@ func fetchRangeHeader(headers http.Header, fullSize uint64) (*layer.RangeParams, return &layer.RangeParams{Start: start, End: end}, nil } +func overrideResponseHeaders(h http.Header, query url.Values) { + for key, value := range query { + if hdr, ok := api.ResponseModifiers[strings.ToLower(key)]; ok { + h[hdr] = value + } + } +} + func writeHeaders(h http.Header, info *data.ObjectInfo, tagSetLength int) { - if len(info.ContentType) > 0 { + if len(info.ContentType) > 0 && h.Get(api.ContentType) == "" { h.Set(api.ContentType, info.ContentType) } h.Set(api.LastModified, info.Created.UTC().Format(http.TimeFormat)) @@ -131,6 +140,9 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) { return } + if layer.IsAuthenticatedRequest(r.Context()) { + overrideResponseHeaders(w.Header(), reqInfo.URL.Query()) + } writeHeaders(w.Header(), info, len(tagSet)) if params != nil { writeRangeHeaders(w, params, info.Size) diff --git a/api/headers.go b/api/headers.go index bca58da29..87999a483 100644 --- a/api/headers.go +++ b/api/headers.go @@ -67,3 +67,13 @@ const ( const ( QueryVersionID = "versionId" ) + +// ResponseModifiers maps response modifies headers to regular headers. +var ResponseModifiers = map[string]string{ + "response-content-type": ContentType, + "response-content-language": ContentLanguage, + "response-expires": Expires, + "response-cache-control": CacheControl, + "response-content-disposition": ContentDisposition, + "response-content-encoding": ContentEncoding, +} diff --git a/api/layer/layer.go b/api/layer/layer.go index 367025eec..1aadd740b 100644 --- a/api/layer/layer.go +++ b/api/layer/layer.go @@ -276,6 +276,12 @@ func (n *layer) EphemeralKey() *keys.PublicKey { return n.anonKey.Key.PublicKey() } +// IsAuthenticatedRequest check if access box exists in current request. +func IsAuthenticatedRequest(ctx context.Context) bool { + _, ok := ctx.Value(api.BoxData).(*accessbox.Box) + return ok +} + // Owner returns owner id from BearerToken (context) or from client owner. func (n *layer) Owner(ctx context.Context) *owner.ID { if data, ok := ctx.Value(api.BoxData).(*accessbox.Box); ok && data != nil && data.Gate != nil {