in source/s3_auto_ranged_get.c [504:628]
static void s_s3_auto_ranged_get_request_finished(
struct aws_s3_meta_request *meta_request,
struct aws_s3_request *request,
int error_code) {
AWS_PRECONDITION(meta_request);
AWS_PRECONDITION(meta_request->impl);
AWS_PRECONDITION(request);
struct aws_s3_auto_ranged_get *auto_ranged_get = meta_request->impl;
AWS_PRECONDITION(auto_ranged_get);
uint64_t total_object_size = 0ULL;
uint64_t total_content_length = 0ULL;
uint64_t object_range_start = 0ULL;
uint64_t object_range_end = 0ULL;
bool found_object_size = false;
bool request_failed = error_code != AWS_ERROR_SUCCESS;
if (request->discovers_object_size) {
/* Try to discover the object-range and content length.*/
if (s_discover_object_range_and_content_length(
meta_request,
request,
error_code,
&total_content_length,
&object_range_start,
&object_range_end,
&total_object_size)) {
error_code = aws_last_error_or_unknown();
goto update_synced_data;
}
/* If we were able to discover the object-range/content length successfully, then any error code that was passed
* into this function is being handled and does not indicate an overall failure.*/
error_code = AWS_ERROR_SUCCESS;
found_object_size = true;
if (meta_request->headers_callback != NULL) {
struct aws_http_headers *response_headers = aws_http_headers_new(meta_request->allocator);
copy_http_headers(request->send_data.response_headers, response_headers);
/* If this request is a part, then the content range isn't applicable. */
if (request->request_tag == AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_PART) {
/* For now, we can assume that discovery of size via the first part of the object does not apply to
* breaking up a ranged request. If it ever does, then we will need to repopulate this header. */
AWS_ASSERT(!auto_ranged_get->initial_message_has_range_header);
aws_http_headers_erase(response_headers, g_content_range_header_name);
}
char content_length_buffer[64] = "";
snprintf(content_length_buffer, sizeof(content_length_buffer), "%" PRIu64, total_content_length);
aws_http_headers_set(
response_headers, g_content_length_header_name, aws_byte_cursor_from_c_str(content_length_buffer));
if (meta_request->headers_callback(
meta_request,
response_headers,
s_s3_auto_ranged_get_success_status(meta_request),
meta_request->user_data)) {
error_code = aws_last_error_or_unknown();
}
meta_request->headers_callback = NULL;
aws_http_headers_release(response_headers);
}
}
update_synced_data:
aws_s3_meta_request_lock_synced_data(meta_request);
/* If the object range was found, then record it. */
if (found_object_size) {
AWS_ASSERT(!auto_ranged_get->synced_data.object_range_known);
auto_ranged_get->synced_data.object_range_known = true;
auto_ranged_get->synced_data.object_range_start = object_range_start;
auto_ranged_get->synced_data.object_range_end = object_range_end;
auto_ranged_get->synced_data.total_num_parts =
aws_s3_get_num_parts(meta_request->part_size, object_range_start, object_range_end);
}
switch (request->request_tag) {
case AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_HEAD_OBJECT:
auto_ranged_get->synced_data.head_object_completed = true;
AWS_LOGF_DEBUG(AWS_LS_S3_META_REQUEST, "id=%p Head object completed.", (void *)meta_request);
break;
case AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_PART:
++auto_ranged_get->synced_data.num_parts_completed;
if (!request_failed) {
++auto_ranged_get->synced_data.num_parts_successful;
aws_s3_meta_request_stream_response_body_synced(meta_request, request);
AWS_LOGF_DEBUG(
AWS_LS_S3_META_REQUEST,
"id=%p: %d out of %d parts have completed.",
(void *)meta_request,
(auto_ranged_get->synced_data.num_parts_successful + auto_ranged_get->synced_data.num_parts_failed),
auto_ranged_get->synced_data.total_num_parts);
} else {
++auto_ranged_get->synced_data.num_parts_failed;
}
break;
case AWS_S3_AUTO_RANGE_GET_REQUEST_TYPE_INITIAL_MESSAGE:
AWS_LOGF_DEBUG(
AWS_LS_S3_META_REQUEST, "id=%p Get of file using initial message completed.", (void *)meta_request);
auto_ranged_get->synced_data.get_without_range_completed = true;
break;
}
if (error_code != AWS_ERROR_SUCCESS) {
aws_s3_meta_request_set_fail_synced(meta_request, request, error_code);
}
aws_s3_meta_request_unlock_synced_data(meta_request);
}