[#310] Support response headers overriding

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-01-21 12:52:16 +03:00 committed by Angira Kekteeva
parent f19c9315ea
commit 2b4ed8487b
3 changed files with 29 additions and 1 deletions

View file

@ -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)

View file

@ -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,
}

View file

@ -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 {