Skip to content

Commit

Permalink
Handle the scenario where the listing is truncated but the "NextMarke…
Browse files Browse the repository at this point in the history
…r" key is missing from the server response. In such cases, use the last listed item as the "NextMarker" value (issue #122)

Documentation:
https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html
  • Loading branch information
mpatrascoiu committed Dec 30, 2024
1 parent d6df7e0 commit 15ef1a3
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/xml/s3propparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ struct S3PropParser::Internal{
S3ListingMode::S3ListingMode _s3_listing_mode;

bool istruncated = false;
std::string nextmarker = "";
std::string nextmarker;
std::string nextmarker_last_key;

int start_elem(const std::string &elem){
// new tag, clean content;
Expand Down Expand Up @@ -110,20 +111,21 @@ struct S3PropParser::Internal{
prefix = current;
if(inside_com_prefix){ // all keys would have been processed by now, just common prefixes left, use as DIRs
DAVIX_SLOG(DAVIX_LOG_TRACE, DAVIX_LOG_XML, "push new common prefix {}", current.c_str());
// Save key for "truncated reply with missing NextMarker" scenario
nextmarker_last_key = current;
current = current.erase(current.size()-1,1);
property.filename = current.erase(0, prefix_to_remove.size());
property.info.mode = 0755 | S_IFDIR;
property.info.mode &= ~(S_IFREG);
props.push_back(property);
prop_count++;
if (istruncated) {
nextmarker = current;
}
}
}

// new name new fileprop
if( StrUtil::compare_ncase(name_prop, elem) ==0){
// Save key for "truncated reply with missing NextMarker" scenario
nextmarker_last_key = current;

if(_s3_listing_mode == S3ListingMode::Flat) { // flat mode
property.filename = current.erase(0,prefix.size());
Expand Down Expand Up @@ -271,7 +273,15 @@ std::deque<FileProperties> & S3PropParser::getProperties(){
}

std::string S3PropParser::getNextMarker() {
return (d_ptr->istruncated ? d_ptr->nextmarker : "");
if (d_ptr->istruncated) {
if (!d_ptr->nextmarker.empty()) {
return d_ptr->nextmarker;
}

return d_ptr->nextmarker_last_key;
}

return "";
}


Expand Down

0 comments on commit 15ef1a3

Please sign in to comment.