|
|
@ -173,11 +173,13 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r |
|
|
|
if api.CacheAPI() != nil { |
|
|
|
if api.CacheAPI() != nil { |
|
|
|
getObjectNInfo = api.CacheAPI().GetObjectNInfo |
|
|
|
getObjectNInfo = api.CacheAPI().GetObjectNInfo |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
getObject := func(offset, length int64) (rc io.ReadCloser, err error) { |
|
|
|
getObject := func(offset, length int64) (rc io.ReadCloser, err error) { |
|
|
|
isSuffixLength := false |
|
|
|
isSuffixLength := false |
|
|
|
if offset < 0 { |
|
|
|
if offset < 0 { |
|
|
|
isSuffixLength = true |
|
|
|
isSuffixLength = true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rs := &HTTPRangeSpec{ |
|
|
|
rs := &HTTPRangeSpec{ |
|
|
|
IsSuffixLength: isSuffixLength, |
|
|
|
IsSuffixLength: isSuffixLength, |
|
|
|
Start: offset, |
|
|
|
Start: offset, |
|
|
@ -193,6 +195,20 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// filter object lock metadata if permission does not permit
|
|
|
|
|
|
|
|
getRetPerms := checkRequestAuthType(ctx, r, policy.GetObjectRetentionAction, bucket, object) |
|
|
|
|
|
|
|
legalHoldPerms := checkRequestAuthType(ctx, r, policy.GetObjectLegalHoldAction, bucket, object) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// filter object lock metadata if permission does not permit
|
|
|
|
|
|
|
|
objInfo.UserDefined = objectlock.FilterObjectLockMetadata(objInfo.UserDefined, getRetPerms != ErrNone, legalHoldPerms != ErrNone) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if objectAPI.IsEncryptionSupported() { |
|
|
|
|
|
|
|
if _, err = DecryptObjectInfo(&objInfo, r.Header); err != nil { |
|
|
|
|
|
|
|
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
s3Select, err := s3select.NewS3Select(r.Body) |
|
|
|
s3Select, err := s3select.NewS3Select(r.Body) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
if serr, ok := err.(s3select.SelectError); ok { |
|
|
|
if serr, ok := err.(s3select.SelectError); ok { |
|
|
@ -212,12 +228,6 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
getRetPerms := checkRequestAuthType(ctx, r, policy.GetObjectRetentionAction, bucket, object) |
|
|
|
|
|
|
|
legalHoldPerms := checkRequestAuthType(ctx, r, policy.GetObjectLegalHoldAction, bucket, object) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// filter object lock metadata if permission does not permit
|
|
|
|
|
|
|
|
objInfo.UserDefined = objectlock.FilterObjectLockMetadata(objInfo.UserDefined, getRetPerms != ErrNone, legalHoldPerms != ErrNone) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if err = s3Select.Open(getObject); err != nil { |
|
|
|
if err = s3Select.Open(getObject); err != nil { |
|
|
|
if serr, ok := err.(s3select.SelectError); ok { |
|
|
|
if serr, ok := err.(s3select.SelectError); ok { |
|
|
|
encodedErrorResponse := encodeResponse(APIErrorResponse{ |
|
|
|
encodedErrorResponse := encodeResponse(APIErrorResponse{ |
|
|
@ -236,6 +246,24 @@ func (api objectAPIHandlers) SelectObjectContentHandler(w http.ResponseWriter, r |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set encryption response headers
|
|
|
|
|
|
|
|
if objectAPI.IsEncryptionSupported() { |
|
|
|
|
|
|
|
if crypto.IsEncrypted(objInfo.UserDefined) { |
|
|
|
|
|
|
|
switch { |
|
|
|
|
|
|
|
case crypto.S3.IsEncrypted(objInfo.UserDefined): |
|
|
|
|
|
|
|
w.Header().Set(crypto.SSEHeader, crypto.SSEAlgorithmAES256) |
|
|
|
|
|
|
|
case crypto.SSEC.IsEncrypted(objInfo.UserDefined): |
|
|
|
|
|
|
|
// Validate the SSE-C Key set in the header.
|
|
|
|
|
|
|
|
if _, err = crypto.SSEC.UnsealObjectKey(r.Header, objInfo.UserDefined, bucket, object); err != nil { |
|
|
|
|
|
|
|
writeErrorResponseHeadersOnly(w, toAPIError(ctx, err)) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
w.Header().Set(crypto.SSECAlgorithm, r.Header.Get(crypto.SSECAlgorithm)) |
|
|
|
|
|
|
|
w.Header().Set(crypto.SSECKeyMD5, r.Header.Get(crypto.SSECKeyMD5)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
s3Select.Evaluate(w) |
|
|
|
s3Select.Evaluate(w) |
|
|
|
s3Select.Close() |
|
|
|
s3Select.Close() |
|
|
|
|
|
|
|
|
|
|
|