@ -429,30 +429,41 @@ type GetObjectReader struct {
pReader io . Reader
cleanUpFns [ ] func ( )
precondFn func ( ObjectInfo , string ) bool
once sync . Once
}
// NewGetObjectReaderFromReader sets up a GetObjectReader with a given
// reader. This ignores any object properties.
func NewGetObjectReaderFromReader ( r io . Reader , oi ObjectInfo , cleanupFns ... func ( ) ) * GetObjectReader {
func NewGetObjectReaderFromReader ( r io . Reader , oi ObjectInfo , pcfn CheckCopyPreconditionFn , cleanupFns ... func ( ) ) ( * GetObjectReader , error ) {
if pcfn != nil {
if ok := pcfn ( oi , "" ) ; ok {
// Call the cleanup funcs
for i := len ( cleanupFns ) - 1 ; i >= 0 ; i -- {
cleanupFns [ i ] ( )
}
return nil , PreConditionFailed { }
}
}
return & GetObjectReader {
ObjInfo : oi ,
pReader : r ,
cleanUpFns : cleanupFns ,
}
precondFn : pcfn ,
} , nil
}
// ObjReaderFn is a function type that takes a reader and returns
// GetObjectReader and an error. Request headers are passed to provide
// encryption parameters. cleanupFns allow cleanup funcs to be
// registered for calling after usage of the reader.
type ObjReaderFn func ( inputReader io . Reader , h http . Header , cleanupFns ... func ( ) ) ( r * GetObjectReader , err error )
type ObjReaderFn func ( inputReader io . Reader , h http . Header , pcfn CheckCopyPreconditionFn , cleanupFns ... func ( ) ) ( r * GetObjectReader , err error )
// NewGetObjectReader creates a new GetObjectReader. The cleanUpFns
// are called on Close() in reverse order as passed here. NOTE: It is
// assumed that clean up functions do not panic (otherwise, they may
// not all run!).
func NewGetObjectReader ( rs * HTTPRangeSpec , oi ObjectInfo , cleanUpFns ... func ( ) ) (
func NewGetObjectReader ( rs * HTTPRangeSpec , oi ObjectInfo , pcfn CheckCopyPreconditionFn , cleanUpFns ... func ( ) ) (
fn ObjReaderFn , off , length int64 , err error ) {
// Call the clean-up functions immediately in case of exit
@ -493,7 +504,7 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, cleanUpFns ...func())
// a reader that returns the desired range of
// encrypted bytes. The header parameter is used to
// provide encryption parameters.
fn = func ( inputReader io . Reader , h http . Header , cFns ... func ( ) ) ( r * GetObjectReader , err error ) {
fn = func ( inputReader io . Reader , h http . Header , pcfn CheckCopyPreconditionFn , cFns ... func ( ) ) ( r * GetObjectReader , err error ) {
copySource := h . Get ( crypto . SSECopyAlgorithm ) != ""
cFns = append ( cleanUpFns , cFns ... )
@ -508,9 +519,18 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, cleanUpFns ...func())
}
return nil , err
}
// Decrypt the ETag before top layer consumes this value.
oi . ETag = getDecryptedETag ( h , oi , copySource )
encETag := oi . ETag
oi . ETag = getDecryptedETag ( h , oi , copySource ) // Decrypt the ETag before top layer consumes this value.
if pcfn != nil {
if ok := pcfn ( oi , encETag ) ; ok {
// Call the cleanup funcs
for i := len ( cFns ) - 1 ; i >= 0 ; i -- {
cFns [ i ] ( )
}
return nil , PreConditionFailed { }
}
}
// Apply the skipLen and limit on the
// decrypted stream
@ -521,6 +541,7 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, cleanUpFns ...func())
ObjInfo : oi ,
pReader : decReader ,
cleanUpFns : cFns ,
precondFn : pcfn ,
}
return r , nil
}
@ -552,7 +573,17 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, cleanUpFns ...func())
return nil , 0 , 0 , errInvalidRange
}
}
fn = func ( inputReader io . Reader , _ http . Header , cFns ... func ( ) ) ( r * GetObjectReader , err error ) {
fn = func ( inputReader io . Reader , _ http . Header , pcfn CheckCopyPreconditionFn , cFns ... func ( ) ) ( r * GetObjectReader , err error ) {
cFns = append ( cleanUpFns , cFns ... )
if pcfn != nil {
if ok := pcfn ( oi , "" ) ; ok {
// Call the cleanup funcs
for i := len ( cFns ) - 1 ; i >= 0 ; i -- {
cFns [ i ] ( )
}
return nil , PreConditionFailed { }
}
}
// Decompression reader.
snappyReader := snappy . NewReader ( inputReader )
// Apply the skipLen and limit on the
@ -564,7 +595,8 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, cleanUpFns ...func())
r = & GetObjectReader {
ObjInfo : oi ,
pReader : decReader ,
cleanUpFns : append ( cleanUpFns , cFns ... ) ,
cleanUpFns : cFns ,
precondFn : pcfn ,
}
return r , nil
}
@ -574,11 +606,22 @@ func NewGetObjectReader(rs *HTTPRangeSpec, oi ObjectInfo, cleanUpFns ...func())
if err != nil {
return nil , 0 , 0 , err
}
fn = func ( inputReader io . Reader , _ http . Header , cFns ... func ( ) ) ( r * GetObjectReader , err error ) {
fn = func ( inputReader io . Reader , _ http . Header , pcfn CheckCopyPreconditionFn , cFns ... func ( ) ) ( r * GetObjectReader , err error ) {
cFns = append ( cleanUpFns , cFns ... )
if pcfn != nil {
if ok := pcfn ( oi , "" ) ; ok {
// Call the cleanup funcs
for i := len ( cFns ) - 1 ; i >= 0 ; i -- {
cFns [ i ] ( )
}
return nil , PreConditionFailed { }
}
}
r = & GetObjectReader {
ObjInfo : oi ,
pReader : inputReader ,
cleanUpFns : append ( cleanUpFns , cFns ... ) ,
cleanUpFns : cFns ,
precondFn : pcfn ,
}
return r , nil
}