Skip to content

Commit

Permalink
Bug 1946: Hang when S3 server returns a truncated listing with folder…
Browse files Browse the repository at this point in the history
…s only

https://winscp.net/tracker/1946
(cherry picked from commit c99d121)

Source commit: 4f58f62525e13801145af0971f6ae94cba25bf3d
  • Loading branch information
martinprikryl committed Jan 26, 2021
1 parent 2ee282d commit 780b773
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions source/core/S3FileSystem.cpp
Expand Up @@ -739,7 +739,7 @@ void TS3FileSystem::TryOpenDirectory(const UnicodeString & Directory)
{
FTerminal->LogEvent(FORMAT(L"Trying to open directory \"%s\".", (Directory)));
std::unique_ptr<TRemoteFileList> FileList(new TRemoteFileList());
ReadDirectoryInternal(Directory, FileList.get(), 1, UnicodeString());
ReadDirectoryInternal(Directory, FileList.get(), -1, UnicodeString());
}
//---------------------------------------------------------------------------
void __fastcall TS3FileSystem::ChangeDirectory(const UnicodeString ADirectory)
Expand Down Expand Up @@ -901,9 +901,10 @@ void TS3FileSystem::ReadDirectoryInternal(
MaxKeys = 0;
}

int AMaxKeys = (MaxKeys == -1) ? 1 : MaxKeys;
S3_list_service(
FLibS3Protocol, FAccessKeyId.c_str(), FSecretAccessKey.c_str(), FSecurityToken, (FHostName + FPortSuffix).c_str(),
StrToS3(FAuthRegion), MaxKeys, FRequestContext, FTimeout, &ListServiceHandler, &Data);
StrToS3(FAuthRegion), AMaxKeys, FRequestContext, FTimeout, &ListServiceHandler, &Data);

HandleNonBucketStatus(Data, Retry);
}
Expand Down Expand Up @@ -932,13 +933,20 @@ void TS3FileSystem::ReadDirectoryInternal(

Continue = false;

if (Data.IsTruncated && ((MaxKeys == 0) || (Data.KeyCount < MaxKeys)))
if (Data.IsTruncated)
{
bool Cancel = false;
FTerminal->DoReadDirectoryProgress(FileList->Count, false, Cancel);
if (!Cancel)
// We have report that with max-keys=1, server can return IsTruncated response with no keys,
// so we would loop infinitelly. For now, if we do GET request only to check for bucket/folder existence (MaxKeys == -1),
// we are happy with a successfull response and never loop, even if IsTruncated.
if ((MaxKeys == 0) ||
((MaxKeys > 0) && (Data.KeyCount < MaxKeys)))
{
Continue = true;
bool Cancel = false;
FTerminal->DoReadDirectoryProgress(FileList->Count, false, Cancel);
if (!Cancel)
{
Continue = true;
}
}
}
} while (Continue);
Expand Down

0 comments on commit 780b773

Please sign in to comment.