WIP: fix COR-239
This commit is contained in:
parent
7e2b9dab62
commit
8762e62b2f
@ -1,6 +1,7 @@
|
||||
package drive
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
@ -366,6 +367,14 @@ func downloadContent(
|
||||
itemID := ptr.Val(item.GetId())
|
||||
ctx = clues.Add(ctx, "item_id", itemID)
|
||||
|
||||
// attempt to fetch item content directly via API
|
||||
// before falling back to fetch content in chunks
|
||||
contentBytes, err := iaag.GetItemContent(ctx, driveID, ptr.Val(item.GetId()))
|
||||
if err == nil {
|
||||
reader := bytes.NewReader(contentBytes)
|
||||
return io.NopCloser(reader), nil
|
||||
}
|
||||
|
||||
content, err := downloadItem(ctx, iaag, item)
|
||||
if err == nil {
|
||||
return content, nil
|
||||
|
||||
@ -733,7 +733,7 @@ func (suite *GetDriveItemUnitTestSuite) TestDownloadContent() {
|
||||
},
|
||||
{
|
||||
name: "expired url redownloads",
|
||||
mgi: getsItem{Item: itemWID, Err: nil},
|
||||
mgi: getsItem{Item: itemWID, Err: nil, ContentErr: assert.AnError},
|
||||
itemInfo: details.ItemInfo{},
|
||||
respBody: []io.ReadCloser{nil, iorc},
|
||||
getErr: []error{errUnauth, nil},
|
||||
@ -744,6 +744,7 @@ func (suite *GetDriveItemUnitTestSuite) TestDownloadContent() {
|
||||
{
|
||||
name: "immediate error",
|
||||
itemInfo: details.ItemInfo{},
|
||||
mgi: getsItem{ContentErr: assert.AnError},
|
||||
getErr: []error{assert.AnError},
|
||||
expectErr: require.Error,
|
||||
expect: require.Nil,
|
||||
@ -753,14 +754,14 @@ func (suite *GetDriveItemUnitTestSuite) TestDownloadContent() {
|
||||
name: "re-fetching the item fails",
|
||||
itemInfo: details.ItemInfo{},
|
||||
getErr: []error{errUnauth},
|
||||
mgi: getsItem{Item: nil, Err: assert.AnError},
|
||||
mgi: getsItem{Item: nil, Err: assert.AnError, ContentErr: assert.AnError},
|
||||
expectErr: require.Error,
|
||||
expect: require.Nil,
|
||||
muc: m,
|
||||
},
|
||||
{
|
||||
name: "expired url fails redownload",
|
||||
mgi: getsItem{Item: itemWID, Err: nil},
|
||||
mgi: getsItem{Item: itemWID, Err: nil, ContentErr: assert.AnError},
|
||||
itemInfo: details.ItemInfo{},
|
||||
respBody: []io.ReadCloser{nil, nil},
|
||||
getErr: []error{errUnauth, assert.AnError},
|
||||
@ -770,7 +771,7 @@ func (suite *GetDriveItemUnitTestSuite) TestDownloadContent() {
|
||||
},
|
||||
{
|
||||
name: "url refreshed from cache",
|
||||
mgi: getsItem{Item: itemWID, Err: nil},
|
||||
mgi: getsItem{Item: itemWID, Err: nil, ContentErr: assert.AnError},
|
||||
itemInfo: details.ItemInfo{},
|
||||
respBody: []io.ReadCloser{nil, iorc},
|
||||
getErr: []error{errUnauth, nil},
|
||||
@ -788,7 +789,7 @@ func (suite *GetDriveItemUnitTestSuite) TestDownloadContent() {
|
||||
},
|
||||
{
|
||||
name: "url refreshed from cache but item deleted",
|
||||
mgi: getsItem{Item: itemWID, Err: core.ErrNotFound},
|
||||
mgi: getsItem{Item: itemWID, Err: core.ErrNotFound, ContentErr: assert.AnError},
|
||||
itemInfo: details.ItemInfo{},
|
||||
respBody: []io.ReadCloser{nil, nil, nil},
|
||||
getErr: []error{errUnauth, core.ErrNotFound, core.ErrNotFound},
|
||||
@ -806,7 +807,7 @@ func (suite *GetDriveItemUnitTestSuite) TestDownloadContent() {
|
||||
},
|
||||
{
|
||||
name: "fallback to item fetch on any cache error",
|
||||
mgi: getsItem{Item: itemWID, Err: nil},
|
||||
mgi: getsItem{Item: itemWID, Err: nil, ContentErr: assert.AnError},
|
||||
itemInfo: details.ItemInfo{},
|
||||
respBody: []io.ReadCloser{nil, iorc},
|
||||
getErr: []error{errUnauth, nil},
|
||||
@ -818,6 +819,14 @@ func (suite *GetDriveItemUnitTestSuite) TestDownloadContent() {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "fetches item content via direct API call",
|
||||
mgi: getsItem{Item: itemWID, Err: nil, ContentErr: nil},
|
||||
itemInfo: details.ItemInfo{},
|
||||
respBody: []io.ReadCloser{nil, iorc},
|
||||
expectErr: require.NoError,
|
||||
expect: require.NotNil,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.Run(test.name, func() {
|
||||
|
||||
@ -83,6 +83,11 @@ type GetItemer interface {
|
||||
ctx context.Context,
|
||||
driveID, itemID string,
|
||||
) (models.DriveItemable, error)
|
||||
|
||||
GetItemContent(
|
||||
ctx context.Context,
|
||||
driveID, itemID string,
|
||||
) ([]byte, error)
|
||||
}
|
||||
|
||||
type EnumerateDriveItemsDeltaer interface {
|
||||
|
||||
@ -869,6 +869,10 @@ func (h mockBackupHandler[T]) GetItem(ctx context.Context, _, _ string) (models.
|
||||
return h.GI.GetItem(ctx, "", "")
|
||||
}
|
||||
|
||||
func (h mockBackupHandler[T]) GetItemContent(ctx context.Context, _, _ string) ([]byte, error) {
|
||||
return h.GI.GetItemContent(ctx, "", "")
|
||||
}
|
||||
|
||||
func (h mockBackupHandler[T]) GetItemPermission(
|
||||
ctx context.Context,
|
||||
_, _ string,
|
||||
@ -978,6 +982,7 @@ func (h mockBackupHandler[T]) GetRootFolder(context.Context, string) (models.Dri
|
||||
type getsItem struct {
|
||||
Item models.DriveItemable
|
||||
Err error
|
||||
ContentErr error
|
||||
}
|
||||
|
||||
func (m getsItem) GetItem(
|
||||
@ -987,6 +992,17 @@ func (m getsItem) GetItem(
|
||||
return m.Item, m.Err
|
||||
}
|
||||
|
||||
func (m getsItem) GetItemContent(
|
||||
_ context.Context,
|
||||
_, _ string,
|
||||
) ([]byte, error) {
|
||||
if m.ContentErr != nil {
|
||||
return nil, m.ContentErr
|
||||
}
|
||||
|
||||
return []byte("fnords"), nil
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Drive Item Enummerator
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@ -167,6 +167,13 @@ func (h siteBackupHandler) GetItem(
|
||||
return h.ac.GetItem(ctx, driveID, itemID)
|
||||
}
|
||||
|
||||
func (h siteBackupHandler) GetItemContent(
|
||||
ctx context.Context,
|
||||
driveID, itemID string,
|
||||
) ([]byte, error) {
|
||||
return h.ac.GetItemContent(ctx, driveID, itemID)
|
||||
}
|
||||
|
||||
func (h siteBackupHandler) IsAllPass() bool {
|
||||
return h.scope.IsAny(selectors.SharePointLibraryFolder)
|
||||
}
|
||||
|
||||
@ -172,6 +172,13 @@ func (h userDriveBackupHandler) GetItem(
|
||||
return h.ac.GetItem(ctx, driveID, itemID)
|
||||
}
|
||||
|
||||
func (h userDriveBackupHandler) GetItemContent(
|
||||
ctx context.Context,
|
||||
driveID, itemID string,
|
||||
) ([]byte, error) {
|
||||
return h.ac.GetItemContent(ctx, driveID, itemID)
|
||||
}
|
||||
|
||||
func (h userDriveBackupHandler) IsAllPass() bool {
|
||||
return h.scope.IsAny(selectors.OneDriveFolder)
|
||||
}
|
||||
|
||||
@ -225,6 +225,10 @@ func (h BackupHandler[T]) GetItem(ctx context.Context, _, _ string) (models.Driv
|
||||
return h.GI.GetItem(ctx, "", "")
|
||||
}
|
||||
|
||||
func (h BackupHandler[T]) GetItemContent(ctx context.Context, _, _ string) ([]byte, error) {
|
||||
return h.GI.GetItemContent(ctx, "", "")
|
||||
}
|
||||
|
||||
func (h BackupHandler[T]) GetItemPermission(
|
||||
ctx context.Context,
|
||||
_, _ string,
|
||||
@ -343,6 +347,13 @@ func (m GetsItem) GetItem(
|
||||
return m.Item, m.Err
|
||||
}
|
||||
|
||||
func (m GetsItem) GetItemContent(
|
||||
_ context.Context,
|
||||
_, _ string,
|
||||
) ([]byte, error) {
|
||||
return nil, m.Err
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Drive Items Enumerator
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@ -136,6 +136,22 @@ func (c Drives) GetItem(
|
||||
return di, nil
|
||||
}
|
||||
|
||||
func (c Drives) GetItemContent(
|
||||
ctx context.Context,
|
||||
driveID, itemID string,
|
||||
) ([]byte, error) {
|
||||
|
||||
dic, err := c.Stable.
|
||||
Client().
|
||||
Drives().
|
||||
ByDriveId(driveID).
|
||||
Items().
|
||||
ByDriveItemId(itemID).Content().Get(ctx, nil)
|
||||
|
||||
return dic, graph.Wrap(ctx, err, "getting item content").OrNil()
|
||||
|
||||
}
|
||||
|
||||
func (c Drives) NewItemContentUpload(
|
||||
ctx context.Context,
|
||||
driveID, itemID string,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user