Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions src/aws-cpp-sdk-core/source/http/curl/CurlHttpClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ struct CurlWriteCallbackContext
m_request(request),
m_response(response),
m_rateLimiter(rateLimiter),
m_numBytesResponseReceived(0)
m_numBytesResponseReceived(0),
m_headersReceivedEventFired(false)
{}

const CurlHttpClient* m_client;
Expand All @@ -147,6 +148,7 @@ struct CurlWriteCallbackContext
HttpResponse* m_response;
Aws::Utils::RateLimits::RateLimiterInterface* m_rateLimiter;
int64_t m_numBytesResponseReceived;
bool m_headersReceivedEventFired;
};

static const char* CURL_HTTP_CLIENT_TAG = "CurlHttpClient";
Expand Down Expand Up @@ -194,11 +196,6 @@ static size_t WriteData(char* ptr, size_t size, size_t nmemb, void* userdata)
}

HttpResponse* response = context->m_response;
auto& headersHandler = context->m_request->GetHeadersReceivedEventHandler();
if (context->m_numBytesResponseReceived == 0 && headersHandler)
{
headersHandler(context->m_request, context->m_response);
}

size_t sizeToWrite = size * nmemb;
if (context->m_rateLimiter)
Expand Down Expand Up @@ -284,6 +281,16 @@ static size_t WriteHeader(char* ptr, size_t size, size_t nmemb, void* userdata)
curl_easy_getinfo(context->m_curlHandle, CURLINFO_RESPONSE_CODE, &responseCode);
response->SetResponseCode(static_cast<HttpResponseCode>(responseCode));
AWS_LOGSTREAM_DEBUG(CURL_HTTP_CLIENT_TAG, "Returned http response code " << responseCode);

if (!context->m_headersReceivedEventFired)
{
auto& headersHandler = context->m_request->GetHeadersReceivedEventHandler();
if (headersHandler)
{
headersHandler(context->m_request, context->m_response);
}
context->m_headersReceivedEventFired = true;
}
}

return size * nmemb;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2690,6 +2690,32 @@ namespace
EXPECT_FALSE(outcome.IsSuccess());
}

TEST_F(BucketAndObjectOperationTest, TestHeadersReceivedEventHandlerFiresOnEmptyBodyResponse) {
const String fullBucketName = CalculateBucketName(BASE_PUT_OBJECTS_BUCKET_NAME.c_str());
SCOPED_TRACE(Aws::String("FullBucketName ") + fullBucketName);

// PutObject returns 200 with headers but an empty body
Aws::S3::Model::PutObjectRequest request;
request.SetBucket(fullBucketName);
request.SetKey("headers-received-handler-test");

auto body = Aws::MakeShared<Aws::StringStream>(ALLOCATION_TAG, "test content");
request.SetBody(body);

std::atomic<bool> handlerFired{false};
Aws::Http::HttpResponseCode capturedCode{Aws::Http::HttpResponseCode::REQUEST_NOT_MADE};
request.SetHeadersReceivedEventHandler(
[&handlerFired, &capturedCode](const Aws::Http::HttpRequest*, Aws::Http::HttpResponse* response) {
handlerFired = true;
capturedCode = response->GetResponseCode();
});

auto outcome = Client->PutObject(request);
AWS_EXPECT_SUCCESS(outcome);
EXPECT_TRUE(handlerFired.load()) << "HeadersReceivedEventHandler must fire even when response body is empty";
EXPECT_EQ(Aws::Http::HttpResponseCode::OK, capturedCode);
}

TEST_F(BucketAndObjectOperationTest, ShouldSkipResponseValidationOnCompositeChecksums) {
const auto fullBucketName = CalculateBucketName(BASE_PUT_MULTIPART_COMPOSITE_CHECKSUM_BUCKET_NAME.c_str());
m_bucketsToDelete.insert(fullBucketName);
Expand Down
Loading