aws-sdk-cpp icon indicating copy to clipboard operation
aws-sdk-cpp copied to clipboard

`Aws::S3::S3Client::GetObject()` hangs on nonexistent key if `SetResponseStreamFactory()` is set

Open specious opened this issue 3 years ago • 0 comments

Describe the bug

Here is the code I'm using inside an AWS Lambda, which hangs and times out when I request an S3 key that does not exist in the bucket:

#include <aws/s3/S3Client.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <aws/core/utils/stream/PreallocatedStreamBuf.h>

// Set the incoming buffer size here
#define IN_BUFFER_SIZE 25 * 1024 * 1024 // 25 MB

// ...

  // Reserve memory for the incoming file data
  Aws::UniqueArrayPtr<unsigned char> inData = Aws::MakeUniqueArray<unsigned char>(IN_BUFFER_SIZE, "in_data");

  // Create a stream buffer object that will fill the preallocated memory
  Aws::Utils::Stream::PreallocatedStreamBuf inStreamBuffer(inData.get(), IN_BUFFER_SIZE);

  // Define a get request for the original object in the S3 media store
  Aws::S3::Model::GetObjectRequest getRequest;
  getRequest.WithBucket(bucketName).SetKey("media/" + objectId);

  // Set the get request to create a custom stream that writes to the preallocated buffer
  getRequest.SetResponseStreamFactory( // <-- causes the problem if key "media/<objectId>" doesn't exist
    [&inStreamBuffer]() -> Aws::IOStream* {
      return Aws::New<Aws::IOStream>("in_stream", &inStreamBuffer);
    }
  );

  std::cout << "getting object from S3: " << getRequest.GetKey() << std::endl;

  // Perform the get request
  Aws::S3::Model::GetObjectOutcome outcome = s3.GetObject(getRequest);

// <-- never gets here if object not found (if custom stream factory is set)

  std::cout << "checking result of get operation\n";

  // Check the outcome of making the get request
  if (!outcome.IsSuccess()) {
    Aws::String error = outcome.GetError().GetMessage();

    std::cout << "get request error: " << error;

    return 1;
  }

Expected Behavior

It should return with key not found error.

Current Behavior

When using the default stream factory, requesting a nonexistent key from the S3 bucket promptly returns with the error message "The specified key does not exist.".

However, when setting getRequest.SetResponseStreamFactory(), everything works perfectly when the key is found and the object is downloaded. However, if the key does not exist, it hangs and never returns.

Reproduction Steps

Possible Solution

I haven't yet figured out why this bug is occurring.

Additional Information/Context

No response

AWS CPP SDK version used

1.9.328

Compiler and Version used

gcc (Alpine 11.2.1_git20220219) 11.2.1 20220219

Operating System and version

Amazon Linux 2 (provided.al2 runtime on AWS Lambda)

specious avatar Sep 09 '22 13:09 specious