in oss/encryption_client.go [134:237]
func (e *EncryptionClient) getObjectSecurely(ctx context.Context, request *GetObjectRequest, optFns ...func(*Options)) (*GetObjectResult, error) {
if request == nil {
return nil, NewErrParamNull("request")
}
var (
err error
httpRange *HTTPRange
discardCount int64 = 0
adjustOffset int64 = 0
closeBody bool = true
)
if request.Range != nil {
httpRange, err = ParseRange(*request.Range)
if err != nil {
return nil, err
}
offset := httpRange.Offset
count := httpRange.Count
adjustOffset = adjustRangeStart(offset, int64(e.alignLen))
discardCount = httpRange.Offset - adjustOffset
if discardCount != 0 {
if count > 0 {
count += discardCount
}
httpRange.Offset = adjustOffset
httpRange.Count = count
}
}
eRequest := request
if httpRange != nil && discardCount > 0 {
_request := *request
eRequest = &_request
eRequest.Range = httpRange.FormatHTTPRange()
eRequest.RangeBehavior = Ptr("standard")
}
result, err := e.client.GetObject(ctx, eRequest, optFns...)
if err != nil {
return nil, err
}
defer func() {
if closeBody && result.Body != nil {
result.Body.Close()
}
}()
if hasEncryptedHeader(result.Headers) {
envelope, err := getEnvelopeFromHeader(result.Headers)
if err != nil {
return nil, err
}
if !isValidContentAlg(envelope.CEKAlg) {
return nil, fmt.Errorf("not supported content algorithm %s,object:%s", envelope.CEKAlg, ToString(request.Key))
}
if !envelope.IsValid() {
return nil, fmt.Errorf("getEnvelopeFromHeader error,object:%s", ToString(request.Key))
}
// use ContentCipherBuilder to decrpt object by default
cc, err := e.getContentCipherBuilder(envelope).ContentCipherEnv(envelope)
if err != nil {
return nil, fmt.Errorf("%s,object:%s", err.Error(), ToString(request.Key))
}
if adjustOffset > 0 {
cipherData := cc.GetCipherData().Clone()
cipherData.SeekIV(uint64(adjustOffset))
cc, _ = cc.Clone(cipherData)
}
result.Body, err = cc.DecryptContent(result.Body)
}
if discardCount > 0 && err == nil {
//rewrite ContentRange & ContentRange
if result.ContentRange != nil {
if from, to, total, cerr := ParseContentRange(*result.ContentRange); cerr == nil {
from += discardCount
value := fmt.Sprintf("bytes %v-%v/%v", from, to, total)
result.ContentRange = Ptr(value)
result.Headers.Set(HTTPHeaderContentRange, value)
}
} else {
result.Headers.Set(HTTPHeaderContentRange, fmt.Sprintf("bytes %v-/*", discardCount))
}
if result.ContentLength > 0 {
result.ContentLength -= discardCount
result.Headers.Set(HTTPHeaderContentLength, fmt.Sprint(result.ContentLength))
}
result.Body = &DiscardReadCloser{
RC: result.Body,
Discard: int(discardCount),
}
}
closeBody = false
return result, err
}