int aws_s3_paginator_continue()

in source/s3_list_objects.c [376:474]


int aws_s3_paginator_continue(struct aws_s3_paginator *paginator, const struct aws_signing_config_aws *signing_config) {
    AWS_PRECONDITION(paginator);

    if (s_set_paginator_state_if_legal(paginator, OS_NOT_STARTED, OS_INITIATED)) {
        return AWS_OP_ERR;
    }

    struct aws_byte_cursor s_path_start = aws_byte_cursor_from_c_str("/?list-type=2");
    struct aws_byte_buf request_path;
    aws_byte_buf_init_copy_from_cursor(&request_path, paginator->allocator, s_path_start);

    if (paginator->prefix) {
        struct aws_byte_cursor s_prefix = aws_byte_cursor_from_c_str("&prefix=");
        aws_byte_buf_append_dynamic(&request_path, &s_prefix);
        struct aws_byte_cursor s_prefix_val = aws_byte_cursor_from_string(paginator->prefix);
        aws_byte_buf_append_encoding_uri_param(&request_path, &s_prefix_val);
    }

    if (paginator->delimiter) {
        struct aws_byte_cursor s_delimiter = aws_byte_cursor_from_c_str("&delimiter=");
        aws_byte_buf_append_dynamic(&request_path, &s_delimiter);
        struct aws_byte_cursor s_delimiter_val = aws_byte_cursor_from_string(paginator->delimiter);
        aws_byte_buf_append_dynamic(&request_path, &s_delimiter_val);
    }

    aws_mutex_lock(&paginator->shared_mt_state.lock);
    if (paginator->shared_mt_state.continuation_token) {
        struct aws_byte_cursor s_continuation = aws_byte_cursor_from_c_str("&continuation-token=");
        aws_byte_buf_append_dynamic(&request_path, &s_continuation);
        struct aws_byte_cursor s_continuation_val =
            aws_byte_cursor_from_string(paginator->shared_mt_state.continuation_token);
        aws_byte_buf_append_encoding_uri_param(&request_path, &s_continuation_val);
    }
    aws_mutex_unlock(&paginator->shared_mt_state.lock);

    struct aws_http_message *list_objects_v2_request = aws_http_message_new_request(paginator->allocator);
    aws_http_message_set_request_path(list_objects_v2_request, aws_byte_cursor_from_buf(&request_path));

    aws_byte_buf_clean_up(&request_path);

    struct aws_byte_cursor host_cur = aws_byte_cursor_from_string(paginator->bucket_name);
    struct aws_byte_buf host_buf;
    aws_byte_buf_init_copy_from_cursor(&host_buf, paginator->allocator, host_cur);
    struct aws_byte_cursor period_cur = aws_byte_cursor_from_c_str(".");
    struct aws_byte_cursor endpoint_val = aws_byte_cursor_from_string(paginator->endpoint);
    aws_byte_buf_append_dynamic(&host_buf, &period_cur);
    aws_byte_buf_append_dynamic(&host_buf, &endpoint_val);

    struct aws_http_header host_header = {
        .name = aws_byte_cursor_from_c_str("host"),
        .value = aws_byte_cursor_from_buf(&host_buf),
    };

    aws_http_message_add_header(list_objects_v2_request, host_header);
    aws_byte_buf_clean_up(&host_buf);

    struct aws_http_header accept_header = {
        .name = aws_byte_cursor_from_c_str("accept"),
        .value = aws_byte_cursor_from_c_str("application/xml"),
    };

    aws_http_message_add_header(list_objects_v2_request, accept_header);

    aws_http_message_set_request_method(list_objects_v2_request, aws_http_method_get);

    struct aws_s3_meta_request_options request_options = {
        .user_data = paginator,
        .signing_config = (struct aws_signing_config_aws *)signing_config,
        .type = AWS_S3_META_REQUEST_TYPE_DEFAULT,
        .body_callback = s_list_bucket_receive_body_callback,
        .finish_callback = s_list_bucket_request_finished,
        .message = list_objects_v2_request,
    };

    /* re-use the current buffer. */
    aws_byte_buf_reset(&paginator->result_body, false);

    /* we're kicking off an asynchronous request. ref-count the paginator to keep it alive until we finish. */
    aws_s3_paginator_acquire(paginator);

    struct aws_s3_meta_request *previous_request = aws_atomic_exchange_ptr(&paginator->current_request, NULL);
    if (previous_request != NULL) {
        /* release request from previous page */
        aws_s3_meta_request_release(previous_request);
    }

    struct aws_s3_meta_request *new_request = aws_s3_client_make_meta_request(paginator->client, &request_options);
    aws_atomic_store_ptr(&paginator->current_request, new_request);

    /* make_meta_request() above, ref counted the http request, so go ahead and release */
    aws_http_message_release(list_objects_v2_request);

    if (new_request == NULL) {
        s_set_paginator_state_if_legal(paginator, OS_INITIATED, OS_ERROR);
        return AWS_OP_ERR;
    }

    return AWS_OP_SUCCESS;
}