Files
DedicatedServerCourse/Plugins/GameLiftPlugin/Source/AWSSDK/Include/aws/s3/s3_client.h

1378 lines
56 KiB
C
Raw Normal View History

#ifndef AWS_S3_CLIENT_H
#define AWS_S3_CLIENT_H
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/auth/signing_config.h>
#include <aws/common/ref_count.h>
#include <aws/io/retry_strategy.h>
#include <aws/s3/s3.h>
AWS_PUSH_SANE_WARNING_LEVEL
struct aws_allocator;
struct aws_http_stream;
struct aws_http_message;
struct aws_http_headers;
struct aws_tls_connection_options;
struct aws_input_stream;
struct aws_hash_table;
struct aws_s3_client;
struct aws_s3_request;
struct aws_s3_meta_request;
struct aws_s3_meta_request_result;
struct aws_s3_meta_request_resume_token;
struct aws_uri;
struct aws_string;
struct aws_s3_request_metrics;
struct aws_s3express_credentials_provider;
struct aws_credentials_properties_s3express;
/**
* A Meta Request represents a group of generated requests that are being done on behalf of the
* original request. For example, one large GetObject request can be transformed into a series
* of ranged GetObject requests that are executed in parallel to improve throughput.
*
* The aws_s3_meta_request_type is a hint of transformation to be applied.
*/
enum aws_s3_meta_request_type {
/**
* The Default meta request type sends any request to S3 as-is (with no transformation). For example,
* it can be used to pass a CreateBucket request.
*/
AWS_S3_META_REQUEST_TYPE_DEFAULT,
/**
* The GetObject request will be split into a series of ranged GetObject requests that are
* executed in parallel to improve throughput, when possible.
*/
AWS_S3_META_REQUEST_TYPE_GET_OBJECT,
/**
* The PutObject request will be split into MultiPart uploads that are executed in parallel
* to improve throughput, when possible.
* Note: put object supports both known and unknown body length. The client
* relies on Content-Length header to determine length of the body.
* Request with unknown content length are always sent using multipart
* upload regardless of final number of parts and do have the following limitations:
* - multipart threshold is ignored and all request are made through mpu,
* even if they only need one part
* - pause/resume is not supported
* - meta request will throw error if checksum header is provider (due to
* general limitation of checksum not being usable if meta request is
* getting split)
*/
AWS_S3_META_REQUEST_TYPE_PUT_OBJECT,
/**
* The CopyObject meta request performs a multi-part copy
* using multiple S3 UploadPartCopy requests in parallel, or bypasses
* a CopyObject request to S3 if the object size is not large enough for
* a multipart upload.
* Note: copy support is still in development and has following limitations:
* - host header must use virtual host addressing style (path style is not
* supported) and both source and dest buckets must have dns compliant name
* - only {bucket}/{key} format is supported for source and passing arn as
* source will not work
* - source bucket is assumed to be in the same region as dest
* - source bucket and dest bucket must both be either directory buckets or regular buckets.
*/
AWS_S3_META_REQUEST_TYPE_COPY_OBJECT,
AWS_S3_META_REQUEST_TYPE_MAX,
};
/**
* The type of a single S3 HTTP request. Used by metrics.
* A meta-request can make multiple S3 HTTP requests under the hood.
*
* For example, AWS_S3_META_REQUEST_TYPE_PUT_OBJECT for a large file will
* do multipart upload, resulting in 3+ HTTP requests:
* AWS_S3_REQUEST_TYPE_CREATE_MULTIPART_UPLOAD, one or more AWS_S3_REQUEST_TYPE_UPLOAD_PART,
* and finally AWS_S3_REQUEST_TYPE_COMPLETE_MULTIPART_UPLOAD.
*
* aws_s3_request_type_operation_name() returns the S3 operation name
* for types that map (e.g. AWS_S3_REQUEST_TYPE_HEAD_OBJECT -> "HeadObject"),
* or empty string for types that don't map (e.g. AWS_S3_REQUEST_TYPE_UNKNOWN -> "").
*/
enum aws_s3_request_type {
/* The actual type of the single S3 HTTP request is unknown */
AWS_S3_REQUEST_TYPE_UNKNOWN,
/* S3 APIs */
AWS_S3_REQUEST_TYPE_HEAD_OBJECT,
AWS_S3_REQUEST_TYPE_GET_OBJECT,
AWS_S3_REQUEST_TYPE_LIST_PARTS,
AWS_S3_REQUEST_TYPE_CREATE_MULTIPART_UPLOAD,
AWS_S3_REQUEST_TYPE_UPLOAD_PART,
AWS_S3_REQUEST_TYPE_ABORT_MULTIPART_UPLOAD,
AWS_S3_REQUEST_TYPE_COMPLETE_MULTIPART_UPLOAD,
AWS_S3_REQUEST_TYPE_UPLOAD_PART_COPY,
AWS_S3_REQUEST_TYPE_COPY_OBJECT,
AWS_S3_REQUEST_TYPE_PUT_OBJECT,
AWS_S3_REQUEST_TYPE_CREATE_SESSION,
/* Max enum value */
AWS_S3_REQUEST_TYPE_MAX,
/** @deprecated Use AWS_S3_REQUEST_TYPE_UNKNOWN if the actual S3 HTTP request type is unknown */
AWS_S3_REQUEST_TYPE_DEFAULT = AWS_S3_REQUEST_TYPE_UNKNOWN,
};
/**
* Invoked to provide response headers received during execution of the meta request, both for
* success and error HTTP status codes.
*
* Return AWS_OP_SUCCESS to continue processing the request.
*
* Return aws_raise_error(E) to cancel the request.
* The error you raise will be reflected in `aws_s3_meta_request_result.error_code`.
* If you're not sure which error to raise, use AWS_ERROR_S3_CANCELED.
*/
typedef int(aws_s3_meta_request_headers_callback_fn)(
struct aws_s3_meta_request *meta_request,
const struct aws_http_headers *headers,
int response_status,
void *user_data);
/**
* Invoked to provide the response body as it is received.
*
* Note: If you set `enable_read_backpressure` true on the S3 client,
* you must maintain the flow-control window.
* The flow-control window shrinks as you receive body data via this callback.
* Whenever the flow-control window reaches 0 you will stop downloading data.
* Use aws_s3_meta_request_increment_read_window() to increment the window and keep data flowing.
* Maintain a larger window to keep up a high download throughput,
* parts cannot download in parallel unless the window is large enough to hold multiple parts.
* Maintain a smaller window to limit the amount of data buffered in memory.
*
* If `manual_window_management` is false, you do not need to maintain the flow-control window.
* No back-pressure is applied and data arrives as fast as possible.
*
* Return AWS_OP_SUCCESS to continue processing the request.
*
* Return aws_raise_error(E) to cancel the request.
* The error you raise will be reflected in `aws_s3_meta_request_result.error_code`.
* If you're not sure which error to raise, use AWS_ERROR_S3_CANCELED.
*/
typedef int(aws_s3_meta_request_receive_body_callback_fn)(
/* The meta request that the callback is being issued for. */
struct aws_s3_meta_request *meta_request,
/* The body data for this chunk of the object. */
const struct aws_byte_cursor *body,
/* The byte index of the object that this refers to. For example, for an HTTP message that has a range header, the
first chunk received will have a range_start that matches the range header's range-start.*/
uint64_t range_start,
/* User data specified by aws_s3_meta_request_options.*/
void *user_data);
/**
* Invoked when the entire meta request execution is complete.
*/
typedef void(aws_s3_meta_request_finish_fn)(
struct aws_s3_meta_request *meta_request,
const struct aws_s3_meta_request_result *meta_request_result,
void *user_data);
/**
* Information sent in the meta_request progress callback.
*/
struct aws_s3_meta_request_progress {
/* Bytes transferred since the previous progress update */
uint64_t bytes_transferred;
/* Length of the entire meta request operation */
uint64_t content_length;
};
/**
* Invoked to report progress of a meta-request.
* For PutObject, progress refers to bytes uploaded.
* For CopyObject, progress refers to bytes copied.
* For GetObject, progress refers to bytes downloaded.
* For anything else, progress refers to response body bytes received.
*/
typedef void(aws_s3_meta_request_progress_fn)(
struct aws_s3_meta_request *meta_request,
const struct aws_s3_meta_request_progress *progress,
void *user_data);
/**
* Invoked to report the telemetry of the meta request once a single request finishes.
* Note: *metrics is only valid for the duration of the callback. If you need to keep it around, use
* `aws_s3_request_metrics_acquire`
*/
typedef void(aws_s3_meta_request_telemetry_fn)(
struct aws_s3_meta_request *meta_request,
struct aws_s3_request_metrics *metrics,
void *user_data);
typedef void(aws_s3_meta_request_shutdown_fn)(void *user_data);
typedef void(aws_s3_client_shutdown_complete_callback_fn)(void *user_data);
enum aws_s3_meta_request_tls_mode {
AWS_MR_TLS_ENABLED,
AWS_MR_TLS_DISABLED,
};
enum aws_s3_meta_request_compute_content_md5 {
AWS_MR_CONTENT_MD5_DISABLED,
AWS_MR_CONTENT_MD5_ENABLED,
};
enum aws_s3_checksum_algorithm {
AWS_SCA_NONE = 0,
AWS_SCA_INIT,
AWS_SCA_CRC32C = AWS_SCA_INIT,
AWS_SCA_CRC32,
AWS_SCA_SHA1,
AWS_SCA_SHA256,
AWS_SCA_END = AWS_SCA_SHA256,
};
enum aws_s3_checksum_location {
AWS_SCL_NONE = 0,
AWS_SCL_HEADER,
AWS_SCL_TRAILER,
};
enum aws_s3_recv_file_option {
/**
* Create a new file if it doesn't exist, otherwise replace the existing file.
*/
AWS_S3_RECV_FILE_CREATE_OR_REPLACE = 0,
/**
* Always create a new file. If the file already exists, AWS_ERROR_S3_RECV_FILE_ALREADY_EXISTS will be raised.
*/
AWS_S3_RECV_FILE_CREATE_NEW,
/**
* Create a new file if it doesn't exist, otherwise append to the existing file.
*/
AWS_S3_RECV_FILE_CREATE_OR_APPEND,
/**
* Write to an existing file at the specified position, defined by the `recv_file_position`.
* If the file does not exist, AWS_ERROR_S3_RECV_FILE_NOT_FOUND will be raised.
* If `recv_file_position` is not configured, start overwriting data at the beginning of the
* file (byte 0).
*/
AWS_S3_RECV_FILE_WRITE_TO_POSITION,
};
/**
* Info about a single part, for you to review before the upload completes.
*/
struct aws_s3_upload_part_review {
/* Size in bytes of this part */
uint64_t size;
/* Checksum string, as sent in the UploadPart request (usually base64-encoded):
* https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html#API_UploadPart_RequestSyntax
* This is empty if no checksum is used. */
struct aws_byte_cursor checksum;
};
/**
* Info for you to review before an upload completes.
*
* WARNING: This feature is experimental/unstable.
* At this time, review is only available for multipart upload
* (when Content-Length is above the `multipart_upload_threshold`,
* or Content-Length not specified).
*/
struct aws_s3_upload_review {
/* The checksum algorithm used. */
enum aws_s3_checksum_algorithm checksum_algorithm;
/* Number of parts uploaded. */
size_t part_count;
/* Array of info about each part uploaded (array is `part_count` in length) */
struct aws_s3_upload_part_review *part_array;
};
/**
* Optional callback, for you to review an upload before it completes.
* For example, you can review each part's checksum and fail the upload if
* you do not agree with them.
*
* @param meta_request pointer to the aws_s3_meta_request of the upload.
* @param info Detailed info about the upload.
*
* Return AWS_OP_SUCCESS to continue processing the request.
*
* Return aws_raise_error(E) to cancel the request.
* The error you raise will be reflected in `aws_s3_meta_request_result.error_code`.
* If you're not sure which error to raise, use AWS_ERROR_S3_CANCELED.
*
* WARNING: This feature is experimental/unstable.
* At this time, the callback is only invoked for multipart upload
* (when Content-Length is above the `multipart_upload_threshold`,
* or Content-Length not specified).
*/
typedef int(aws_s3_meta_request_upload_review_fn)(
struct aws_s3_meta_request *meta_request,
const struct aws_s3_upload_review *review,
void *user_data);
/**
* The factory function for S3 client to create a S3 Express credentials provider.
* The S3 client will be the only owner of the S3 Express credentials provider.
*
* During S3 client destruction, S3 client will start the destruction of the provider, and wait the
* on_provider_shutdown_callback to be invoked before the S3 client finish destruction.
*
* Note to implement the factory properly:
* - Make sure `on_provider_shutdown_callback` will be invoked after the provider finish shutdown, otherwise,
* leak will happen.
* - The provider must not acquire a reference to the client; otherwise, a circular reference will cause a deadlock.
* - The `client` provided CANNOT be used within the factory function call or the destructor.
*
* @param allocator memory allocator to create the provider.
* @param client The S3 client uses and owns the provider.
* @param on_provider_shutdown_callback The callback to be invoked when the provider finishes shutdown.
* @param shutdown_user_data The user data to invoke shutdown callback with
* @param user_data The user data with the factory
*
* @return The aws_s3express_credentials_provider.
*/
typedef struct aws_s3express_credentials_provider *(
aws_s3express_provider_factory_fn)(struct aws_allocator *allocator,
struct aws_s3_client *client,
aws_simple_completion_callback on_provider_shutdown_callback,
void *shutdown_user_data,
void *factory_user_data);
/* Keepalive properties are TCP only.
* If interval or timeout are zero, then default values are used.
*/
struct aws_s3_tcp_keep_alive_options {
uint16_t keep_alive_interval_sec;
uint16_t keep_alive_timeout_sec;
/* If set, sets the number of keep alive probes allowed to fail before the connection is considered
* lost. If zero OS defaults are used. On Windows, this option is meaningless until Windows 10 1703.*/
uint16_t keep_alive_max_failed_probes;
};
/* Options for a new client. */
struct aws_s3_client_config {
/* When set, this will cap the number of active connections. When 0, the client will determine this value based on
* throughput_target_gbps. (Recommended) */
uint32_t max_active_connections_override;
/* Region that the client default to. */
struct aws_byte_cursor region;
/* Client bootstrap used for common staples such as event loop group, host resolver, etc.. s*/
struct aws_client_bootstrap *client_bootstrap;
/* How tls should be used while performing the request
* If this is ENABLED:
* If tls_connection_options is not-null, then those tls options will be used
* If tls_connection_options is NULL, then default tls options will be used
* If this is DISABLED:
* No tls options will be used, regardless of tls_connection_options value.
*/
enum aws_s3_meta_request_tls_mode tls_mode;
/* TLS Options to be used for each connection, if tls_mode is ENABLED. When compiling with BYO_CRYPTO, and tls_mode
* is ENABLED, this is required. Otherwise, this is optional.
*/
const struct aws_tls_connection_options *tls_connection_options;
/**
* Required.
* Configure the signing for the requests made from the client.
* - Credentials or credentials provider is required. Other configs are all optional, and will be default to what
* needs to sign the request for S3, only overrides when Non-zero/Not-empty is set.
* - To skip signing, you can config it with anonymous credentials.
* - S3 Client will derive the right config for signing process based on this.
*
* Notes:
* - For AWS_SIGNING_ALGORITHM_V4_S3EXPRESS, S3 client will use the credentials in the config to derive the
* S3 Express credentials that are used in the signing process.
* - For other auth algorithm, client may make modifications to signing config before passing it on to signer.
*
* TODO: deprecate this structure from auth, introduce a new S3 specific one.
*/
const struct aws_signing_config_aws *signing_config;
/**
* Optional.
* Size of parts the object will be downloaded or uploaded in, in bytes.
* This only affects AWS_S3_META_REQUEST_TYPE_GET_OBJECT and AWS_S3_META_REQUEST_TYPE_PUT_OBJECT.
* If not set, this defaults to 8 MiB.
* The client will adjust the part size for AWS_S3_META_REQUEST_TYPE_PUT_OBJECT if needed for service limits (max
* number of parts per upload is 10,000, minimum upload part size is 5 MiB).
*
* You can also set this per meta-request, via `aws_s3_meta_request_options.part_size`.
*/
uint64_t part_size;
/* If the part size needs to be adjusted for service limits, this is the maximum size it will be adjusted to. On 32
* bit machine, it will be forced to SIZE_MAX, which is around 4GiB. The server limit is 5GiB, but object size limit
* is 5TiB for now. We should be good enough for all the cases. */
uint64_t max_part_size;
/**
* Optional.
* The size threshold in bytes for when to use multipart uploads.
* Uploads larger than this will use the multipart upload strategy.
* Uploads smaller or equal to this will use a single HTTP request.
* This only affects AWS_S3_META_REQUEST_TYPE_PUT_OBJECT.
* If set, this should be at least `part_size`.
* If not set, maximal of `part_size` and 5 MiB will be used.
*
* You can also set this per meta-request, via `aws_s3_meta_request_options.multipart_upload_threshold`.
*/
uint64_t multipart_upload_threshold;
/* Throughput target in gigabits per second (Gbps) that we are trying to reach. */
double throughput_target_gbps;
/* How much memory can we use. This will be capped to SIZE_MAX */
uint64_t memory_limit_in_bytes;
/* Retry strategy to use. If NULL, a default retry strategy will be used. */
struct aws_retry_strategy *retry_strategy;
/**
* TODO: move MD5 config to checksum config.
* For multi-part upload, content-md5 will be calculated if the AWS_MR_CONTENT_MD5_ENABLED is specified
* or initial request has content-md5 header.
* For single-part upload, keep the content-md5 in the initial request unchanged. */
enum aws_s3_meta_request_compute_content_md5 compute_content_md5;
/* Callback and associated user data for when the client has completed its shutdown process. */
aws_s3_client_shutdown_complete_callback_fn *shutdown_callback;
void *shutdown_callback_user_data;
/**
* Optional.
* Proxy configuration for http connection.
* If the connection_type is AWS_HPCT_HTTP_LEGACY, it will be converted to AWS_HPCT_HTTP_TUNNEL if tls_mode is
* ENABLED. Otherwise, it will be converted to AWS_HPCT_HTTP_FORWARD.
*/
const struct aws_http_proxy_options *proxy_options;
/**
* Optional.
* Configuration for fetching proxy configuration from environment.
* By Default proxy_ev_settings.aws_http_proxy_env_var_type is set to AWS_HPEV_ENABLE which means read proxy
* configuration from environment.
* Only works when proxy_options is not set. If both are set, configuration from proxy_options is used.
*/
const struct proxy_env_var_settings *proxy_ev_settings;
/**
* Optional.
* If set to 0, default value is used.
*/
uint32_t connect_timeout_ms;
/**
* Optional.
* Set keepalive to periodically transmit messages for detecting a disconnected peer.
*/
const struct aws_s3_tcp_keep_alive_options *tcp_keep_alive_options;
/**
* Optional.
* Configuration options for connection monitoring.
* If the transfer speed falls below the specified minimum_throughput_bytes_per_second, the operation is aborted.
* If set to NULL, default values are used.
*/
const struct aws_http_connection_monitoring_options *monitoring_options;
/**
* Enable backpressure and prevent response data from downloading faster than you can handle it.
*
* If false (default), no backpressure is applied and data will download as fast as possible.
*
* If true, each meta request has a flow-control window that shrinks as
* response body data is downloaded (headers do not affect the window).
* `initial_read_window` determines the starting size of each meta request's window.
* You will stop downloading data whenever the flow-control window reaches 0
* You must call aws_s3_meta_request_increment_read_window() to keep data flowing.
*
* WARNING: This feature is experimental.
* Currently, backpressure is only applied to GetObject requests which are split into multiple parts,
* and you may still receive some data after the window reaches 0.
*/
bool enable_read_backpressure;
/**
* The starting size of each meta request's flow-control window, in bytes.
* Ignored unless `enable_read_backpressure` is true.
*/
size_t initial_read_window;
/**
* To enable S3 Express support or not.
*/
bool enable_s3express;
/**
* Optional.
* Only used when `enable_s3express` is set.
*
* If set, client will invoke the factory to get the provider to use, when needed.
*
* If not set, client will create a default S3 Express provider under the hood.
*/
aws_s3express_provider_factory_fn *s3express_provider_override_factory;
void *factory_user_data;
/**
* THIS IS AN EXPERIMENTAL AND UNSTABLE API
* (Optional)
* An array of network interface names. The client will distribute the
* connections across network interface names provided in this array. If any interface name is invalid, goes down,
* or has any issues like network access, you will see connection failures.
*
* This option is only supported on Linux, MacOS, and platforms that have either SO_BINDTODEVICE or IP_BOUND_IF. It
* is not supported on Windows. `AWS_ERROR_PLATFORM_NOT_SUPPORTED` will be raised on unsupported platforms. On
* Linux, SO_BINDTODEVICE is used and requires kernel version >= 5.7 or root privileges.
*/
const struct aws_byte_cursor *network_interface_names_array;
size_t num_network_interface_names;
};
struct aws_s3_checksum_config {
/**
* The location of client added checksum header.
*
* If AWS_SCL_NONE. No request payload checksum will be calculated or added.
*
* If AWS_SCL_HEADER, the client will calculate the checksum and add it to the headers.
*
* If AWS_SCL_TRAILER, the payload will be aws_chunked encoded, The client will calculate the checksum and add it to
* the trailer. Note the payload of the original request cannot be aws-chunked encoded already, this will cause an
* error.
*/
enum aws_s3_checksum_location location;
/**
* The checksum algorithm used.
* Must be set if location is not AWS_SCL_NONE.
*/
enum aws_s3_checksum_algorithm checksum_algorithm;
/**
* Enable checksum mode header will be attached to GET requests, this will tell s3 to send back checksums headers if
* they exist. Calculate the corresponding checksum on the response bodies. The meta request will finish with a did
* validate field and set the error code to AWS_ERROR_S3_RESPONSE_CHECKSUM_MISMATCH if the calculated
* checksum, and checksum found in the response header do not match.
*/
bool validate_response_checksum;
/**
* Optional array of `enum aws_s3_checksum_algorithm`.
*
* Ignored when validate_response_checksum is not set.
* If not set all the algorithms will be selected as default behavior.
* Owned by the caller.
*
* The list of algorithms for user to pick up when validate the checksum. Client will pick up the algorithm from the
* list with the priority based on performance, and the algorithm sent by server. The priority based on performance
* is [CRC32C, CRC32, SHA1, SHA256].
*
* If the response checksum was validated by client, the result will indicate which algorithm was picked.
*/
const struct aws_array_list *validate_checksum_algorithms;
};
/**
* Options for a new meta request, ie, file transfer that will be handled by the high performance client.
*
* There are several ways to pass the request's body data:
* 1) If the data is already in memory, set the body-stream on `message`.
* 2) If the data is on disk, set `send_filepath` for best performance.
* 3) If the data is available, but copying each chunk is asynchronous, set `send_async_stream`.
* 4) If you're not sure when each chunk of data will be available, use `send_using_async_writes`.
*/
struct aws_s3_meta_request_options {
/* The type of meta request we will be trying to accelerate. */
enum aws_s3_meta_request_type type;
/**
* The S3 operation name (e.g. "CreateBucket").
* This MUST be set if type is AWS_S3_META_REQUEST_TYPE_DEFAULT;
* it is automatically populated for other meta-request types.
* The canonical operation names are listed here:
* https://docs.aws.amazon.com/AmazonS3/latest/API/API_Operations_Amazon_Simple_Storage_Service.html
*
* This name is used to fill out details in metrics and error reports.
* It also drives some operation-specific behavior.
* If you pass the wrong name, you risk getting the wrong behavior.
*
* For example, every operation except "GetObject" has its response checked
* for error, even if the HTTP status-code was 200 OK
* (see https://repost.aws/knowledge-center/s3-resolve-200-internalerror).
* If you used AWS_S3_META_REQUEST_TYPE_DEFAULT to do GetObject, but mis-named
* it "Download", and the object looked like XML with an error code,
* then the meta-request would fail. You may log the full response body,
* and leak sensitive data.
*/
struct aws_byte_cursor operation_name;
/**
* Configure the signing for each request created for this meta request. If NULL, options in the client will be
* used.
* - The credentials will be obtained based on the precedence of:
* 1. `credentials` from `signing_config` in `aws_s3_meta_request_options`
* 2. `credentials_provider` from `signing_config` in `aws_s3_meta_request_options`
* 3. `credentials` from `signing_config` cached in the client
* 4. `credentials_provider` cached in the client
* - To skip signing, you can config it with anonymous credentials.
* - S3 Client will derive the right config for signing process based on this.
*
* Notes:
* - For AWS_SIGNING_ALGORITHM_V4_S3EXPRESS, S3 client will use the credentials in the config to derive the
* S3 Express credentials that are used in the signing process.
* - For other auth algorithm, client may make modifications to signing config before passing it on to signer.
**/
const struct aws_signing_config_aws *signing_config;
/* Initial HTTP message that defines what operation we are doing.
* Do not set the message's body-stream if the body is being passed by other means (see note above) */
struct aws_http_message *message;
/**
* Optional.
* If set, the received data will be written into this file.
* the `body_callback` will NOT be invoked.
* This gives a better performance when receiving data to write to a file.
* See `aws_s3_recv_file_option` for the configuration on the receive file.
*/
struct aws_byte_cursor recv_filepath;
/**
* Optional.
* Default to AWS_S3_RECV_FILE_CREATE_OR_REPLACE.
* This only works with recv_filepath set.
* See `aws_s3_recv_file_option`.
*/
enum aws_s3_recv_file_option recv_file_option;
/**
* Optional.
* The specified position to start writing at for the recv file when `recv_file_option` is set to
* AWS_S3_RECV_FILE_WRITE_TO_POSITION, ignored otherwise.
*/
uint64_t recv_file_position;
/**
* Set it to be true to delete the receive file on failure, otherwise, the file will be left as-is.
* This only works with recv_filepath set.
*/
bool recv_file_delete_on_failure;
/**
* Optional.
* If set, this file is sent as the request body.
* This gives the best performance when sending data from a file.
* Do not set if the body is being passed by other means (see note above).
*/
struct aws_byte_cursor send_filepath;
/**
* Optional - EXPERIMENTAL/UNSTABLE
* If set, the request body comes from this async stream.
* Use this when outgoing data will be produced in asynchronous chunks.
* The S3 client will read from the stream whenever it's ready to upload another chunk.
*
* WARNING: The S3 client can deadlock if many async streams are "stalled",
* never completing their async read. If you're not sure when (if ever)
* data will be ready, use `send_using_async_writes` instead.
*
* Do not set if the body is being passed by other means (see note above).
*/
struct aws_async_input_stream *send_async_stream;
/**
* Optional - EXPERIMENTAL/UNSTABLE
* Set this to send request body data using the async aws_s3_meta_request_poll_write()
* or aws_s3_meta_request_write() functions.
* Use this when outgoing data will be produced in asynchronous chunks,
* and you're not sure when (if ever) each chunk will be ready.
*
* This only works with AWS_S3_META_REQUEST_TYPE_PUT_OBJECT.
*
* Do not set if the body is being passed by other means (see note above).
*/
bool send_using_async_writes;
/**
* Optional.
* if set, the flexible checksum will be performed by client based on the config.
*/
const struct aws_s3_checksum_config *checksum_config;
/**
* Optional.
* Size of parts the object will be downloaded or uploaded in, in bytes.
* This only affects AWS_S3_META_REQUEST_TYPE_GET_OBJECT and AWS_S3_META_REQUEST_TYPE_PUT_OBJECT.
* If not set, the value from `aws_s3_client_config.part_size` is used, which defaults to 8MiB.
*
* The client will adjust the part size for AWS_S3_META_REQUEST_TYPE_PUT_OBJECT if needed for service limits (max
* number of parts per upload is 10,000, minimum upload part size is 5 MiB).
*/
uint64_t part_size;
/**
* Optional.
* The size threshold in bytes for when to use multipart uploads.
* Uploads larger than this will use the multipart upload strategy.
* Uploads smaller or equal to this will use a single HTTP request.
* This only affects AWS_S3_META_REQUEST_TYPE_PUT_OBJECT.
* If set, this should be at least `part_size`.
* If not set, `part_size` adjusted by client will be used as the threshold.
* If both `part_size` and `multipart_upload_threshold` are not set,
* the values from `aws_s3_client_config` are used.
*/
uint64_t multipart_upload_threshold;
/* User data for all callbacks. */
void *user_data;
/**
* Optional.
* Invoked to provide response headers received during execution of the meta request.
* Note: this callback will not be fired for cases when resuming an
* operation that was already completed (ex. pausing put object after it
* uploaded all data and then resuming it)
* See `aws_s3_meta_request_headers_callback_fn`.
*/
aws_s3_meta_request_headers_callback_fn *headers_callback;
/**
* Invoked to provide the response body as it is received.
* See `aws_s3_meta_request_receive_body_callback_fn`.
*/
aws_s3_meta_request_receive_body_callback_fn *body_callback;
/**
* Invoked when the entire meta request execution is complete.
* See `aws_s3_meta_request_finish_fn`.
*/
aws_s3_meta_request_finish_fn *finish_callback;
/* Callback for when the meta request has completely cleaned up. */
aws_s3_meta_request_shutdown_fn *shutdown_callback;
/**
* Invoked to report progress of the meta request execution.
* See `aws_s3_meta_request_progress_fn`.
*/
aws_s3_meta_request_progress_fn *progress_callback;
/**
* Optional.
* To get telemetry metrics when a single request finishes.
* If set the request will keep track of the metrics from `aws_s3_request_metrics`, and fire the callback when the
* request finishes receiving response.
* See `aws_s3_meta_request_telemetry_fn`
*/
aws_s3_meta_request_telemetry_fn *telemetry_callback;
/**
* Optional.
* Callback for reviewing an upload before it completes.
* WARNING: experimental/unstable
* See `aws_s3_upload_review_fn`
*/
aws_s3_meta_request_upload_review_fn *upload_review_callback;
/**
* Optional.
* Endpoint override for request. Can be used to override scheme and port of
* the endpoint.
* There is some overlap between Host header and Endpoint and corner cases
* are handled as follows:
* - Only Host header is set - Host is used to construct endpoint. https is
* default with corresponding port
* - Only endpoint is set - Host header is created from endpoint. Port and
* Scheme from endpoint is used.
* - Both Host and Endpoint is set - Host header must match Authority of
* Endpoint uri. Port and Scheme from endpoint is used.
*/
const struct aws_uri *endpoint;
/**
* Optional.
* For meta requests that support pause/resume (e.g. PutObject), serialized resume token returned by
* aws_s3_meta_request_pause() can be provided here.
* Note: If PutObject request specifies a checksum algorithm, client will calculate checksums while skipping parts
* from the buffer and compare them them to previously uploaded part checksums.
*/
struct aws_s3_meta_request_resume_token *resume_token;
/*
* Optional.
* Total object size hint, in bytes.
* The optimal strategy for downloading a file depends on its size.
* Set this hint to help the S3 client choose the best strategy for this particular file.
* This is just used as an estimate, so it's okay to provide an approximate value if the exact size is unknown.
*/
const uint64_t *object_size_hint;
};
/* Result details of a meta request.
*
* If error_code is AWS_ERROR_SUCCESS, then response_status will match the response_status passed earlier by the header
* callback and error_response_headers and error_response_body will be NULL.
*
* If error_code is equal to AWS_ERROR_S3_INVALID_RESPONSE_STATUS, then error_response_headers, error_response_body, and
* response_status will be populated by the failed request.
*
* For all other error codes, response_status will be 0, and the error_response variables will be NULL.
*/
struct aws_s3_meta_request_result {
/* If meta request failed due to an HTTP error response from S3, these are the headers.
* NULL if meta request failed for another reason. */
struct aws_http_headers *error_response_headers;
/* If meta request failed due to an HTTP error response from S3, this the body.
* NULL if meta request failed for another reason, or if the response had no body (such as a HEAD response). */
struct aws_byte_buf *error_response_body;
/* If meta request failed due to an HTTP error response from S3,
* this is the name of the S3 operation it was responding to.
* For example, if a AWS_S3_META_REQUEST_TYPE_PUT_OBJECT fails this could be
* "PutObject, "CreateMultipartUpload", "UploadPart", "CompleteMultipartUpload", or others.
* For AWS_S3_META_REQUEST_TYPE_DEFAULT, this is the same value passed to
* aws_s3_meta_request_options.operation_name.
* NULL if the meta request failed for another reason. */
struct aws_string *error_response_operation_name;
/* Response status of the failed request or of the entire meta request. */
int response_status;
/* Only set for GET request.
* Was the server side checksum compared against a calculated checksum of the response body. This may be false
* even if validate_get_response_checksum was set because the object was uploaded without a checksum, or was
* uploaded as a multipart object.
*
* If the object to get is multipart object, the part checksum MAY be validated if the part size to get matches the
* part size uploaded. In that case, if any part mismatch the checksum received, the meta request will fail with
* checksum mismatch. However, even if the parts checksum were validated, this will NOT be set to true, as the
* checksum for the whole meta request was NOT validated.
**/
bool did_validate;
/* algorithm used to validate checksum */
enum aws_s3_checksum_algorithm validation_algorithm;
/* Final error code of the meta request. */
int error_code;
};
AWS_EXTERN_C_BEGIN
AWS_S3_API
struct aws_s3_client *aws_s3_client_new(
struct aws_allocator *allocator,
const struct aws_s3_client_config *client_config);
/**
* Add a reference, keeping this object alive.
* The reference must be released when you are done with it, or it's memory will never be cleaned up.
* You must not pass in NULL.
* Always returns the same pointer that was passed in.
*/
AWS_S3_API
struct aws_s3_client *aws_s3_client_acquire(struct aws_s3_client *client);
/**
* Release a reference.
* When the reference count drops to 0, this object will be cleaned up.
* It's OK to pass in NULL (nothing happens).
* Always returns NULL.
*/
AWS_S3_API
struct aws_s3_client *aws_s3_client_release(struct aws_s3_client *client);
AWS_S3_API
struct aws_s3_meta_request *aws_s3_client_make_meta_request(
struct aws_s3_client *client,
const struct aws_s3_meta_request_options *options);
/**
* The result of an `aws_s3_meta_request_poll_write()` call.
* Think of this like Rust's `Poll<Result<size_t, int>>`, or C++'s `optional<expected<size_t, int>>`.
*/
struct aws_s3_meta_request_poll_write_result {
bool is_pending;
int error_code;
size_t bytes_processed;
};
/**
* Attempt to write data.
*
* You must set `aws_s3_meta_request_options.send_using_async_writes` to use this function.
*
* This is a non-blocking poll-style async function, similar to Rust's:
* https://docs.rs/futures/latest/futures/io/trait.AsyncWrite.html#tymethod.poll_write
* If you prefer completion-style async functions, and your data can outlive
* the callstack, use aws_s3_meta_request_write() instead.
*
* Check the returned `result` struct to see what happened:
* 1) If `result.is_pending == true` then no work was done.
* The waker callback will be invoked when you can call poll_write() again.
* Do not call poll_write() again before the waker is invoked.
*
* 2) Else if `result.error_code != 0` then poll_write() did not succeed
* and you should not call it again. The meta request is guaranteed to finish soon
* (you don't need to worry about canceling the meta request yourself after a failed write).
* A common error code is AWS_ERROR_S3_REQUEST_HAS_COMPLETED, indicating
* the meta request completed for reasons unrelated to the poll_write() call
* (e.g. CreateMultipartUpload received a 403 Forbidden response).
* AWS_ERROR_INVALID_STATE usually indicates that you're calling poll_write()
* incorrectly (e.g. not waiting for waker callback from previous poll_write() call).
*
* 3) Else `result.bytes_processed` tells you how much data was processed.
* `bytes_processed` may be less than the `data.len` you passed in.
* Continue calling poll_write() with the remaining data until everything is processed.
* `result.bytes_processed` won't be 0 unless you passed in `data.len` of 0.
*
* @param meta_request Meta request
*
* @param data The data to send. The data can be any size.
* `result.bytes_processed` indicates how many bytes were
* processed by this call.
*
* @param eof Pass true to signal EOF (end of file).
* If poll_write() doesn't process all your data
* (`result.is_pending` or `result.byte_processed < data.len`)
* then EOF was ignored, and you need to pass it again
* to subsequent poll_write() calls.
*
* @param waker Waker callback.
* If `result.is_pending == true`, then the waker will be called
* exactly once when it's a good time to call poll_write() again.
* If `result.is_pending == false`, the waker will never be called.
*
* @param user_data Pointer to be passed to the waker callback.
*
* WARNING: This feature is experimental.
*/
AWS_S3_API
struct aws_s3_meta_request_poll_write_result aws_s3_meta_request_poll_write(
struct aws_s3_meta_request *meta_request,
struct aws_byte_cursor data,
bool eof,
aws_simple_completion_callback *waker,
void *user_data);
/**
* Write the next chunk of data.
*
* You must set `aws_s3_meta_request_options.send_using_async_writes` to use this function.
*
* This function is asynchronous, and returns a future (see <aws/io/future.h>).
* You may not call write() again until the future completes.
*
* If the future completes with an error code, then write() did not succeed
* and you should not call it again. If the future contains any error code,
* the meta request is guaranteed to finish soon (you don't need to worry about
* canceling the meta request yourself after a failed write).
* A common error code is AWS_ERROR_S3_REQUEST_HAS_COMPLETED, indicating
* the meta request completed for reasons unrelated to the write() call
* (e.g. CreateMultipartUpload received a 403 Forbidden response).
* AWS_ERROR_INVALID_STATE usually indicates that you're calling write()
* incorrectly (e.g. not waiting for previous write to complete).
*
* You MUST keep the data in memory until the future completes.
* If you cannot do this, use aws_s3_meta_request_poll_write() instead.
*
* You can wait any length of time between calls to write().
* If there's not enough data to upload a part, the data will be copied
* to a buffer and the future will immediately complete.
*
* @param meta_request Meta request
*
* @param data The data to send. The data can be any size.
*
* @param eof Pass true to signal EOF (end of file).
* Do not call write() again after passing true.
*
* This function never returns NULL.
*
* WARNING: This feature is experimental.
*/
AWS_S3_API
struct aws_future_void *aws_s3_meta_request_write(
struct aws_s3_meta_request *meta_request,
struct aws_byte_cursor data,
bool eof);
/**
* Increment the flow-control window, so that response data continues downloading.
*
* If the client was created with `enable_read_backpressure` set true,
* each meta request has a flow-control window that shrinks as response
* body data is downloaded (headers do not affect the size of the window).
* The client's `initial_read_window` determines the starting size of each meta request's window.
* If a meta request's flow-control window reaches 0, no further data will be downloaded.
* If the `initial_read_window` is 0, the request will not start until the window is incremented.
* Maintain a larger window to keep up a high download throughput,
* parts cannot download in parallel unless the window is large enough to hold multiple parts.
* Maintain a smaller window to limit the amount of data buffered in memory.
*
* If `enable_read_backpressure` is false this call will have no effect,
* no backpressure is being applied and data is being downloaded as fast as possible.
*
* WARNING: This feature is experimental.
* Currently, backpressure is only applied to GetObject requests which are split into multiple parts,
* and you may still receive some data after the window reaches 0.
*/
AWS_S3_API
void aws_s3_meta_request_increment_read_window(struct aws_s3_meta_request *meta_request, uint64_t bytes);
AWS_S3_API
void aws_s3_meta_request_cancel(struct aws_s3_meta_request *meta_request);
/**
* Note: pause is currently only supported on upload requests.
* In order to pause an ongoing upload, call aws_s3_meta_request_pause() that
* will return resume token. Token can be used to query the state of operation
* at the pausing time.
* To resume an upload that was paused, supply resume token in the meta
* request options structure member aws_s3_meta_request_options.resume_token.
* The upload can be resumed either from the same client or a different one.
* Corner cases for resume upload are as follows:
* - upload is not MPU - fail with AWS_ERROR_UNSUPPORTED_OPERATION
* - pausing before MPU is created - NULL resume token returned. NULL resume
* token is equivalent to restarting upload
* - pausing in the middle of part transfer - return resume token. scheduling of
* new part uploads stops.
* - pausing after completeMPU started - return resume token. if s3 cannot find
* find associated MPU id when resuming with that token and num of parts
* uploaded equals to total num parts, then operation is a no op. Otherwise
* operation fails.
* Note: for no op case the call will succeed and finish/shutdown request callbacks will
* fire, but on headers callback will not fire.
* Note: similar to cancel pause does not cancel requests already in flight and
* and parts might complete after pause is requested.
* @param meta_request pointer to the aws_s3_meta_request of the upload to be paused
* @param resume_token resume token
* @return either AWS_OP_ERR or AWS_OP_SUCCESS
*/
AWS_S3_API
int aws_s3_meta_request_pause(
struct aws_s3_meta_request *meta_request,
struct aws_s3_meta_request_resume_token **out_resume_token);
/*
* Options to construct upload resume token.
* Note: fields correspond to getters on the token below and it up to the caller
* to persist those in whichever way they choose.
*/
struct aws_s3_upload_resume_token_options {
struct aws_byte_cursor upload_id; /* Required */
uint64_t part_size; /* Required. Must be less than SIZE_MAX */
size_t total_num_parts; /* Required */
/**
* Optional.
*
* Note: during resume num_parts_uploaded is used for sanity checking against
* uploads on s3 side.
* In cases where upload id does not exist (already resumed using this token
* or pause called after upload completes, etc...) and num_parts_uploaded
* equals to total num parts, resume will become a noop.
*/
size_t num_parts_completed;
};
/**
* Create upload resume token from persisted data.
* Note: Data required for resume token varies per operation.
*/
AWS_S3_API
struct aws_s3_meta_request_resume_token *aws_s3_meta_request_resume_token_new_upload(
struct aws_allocator *allocator,
const struct aws_s3_upload_resume_token_options *options);
/*
* Increment resume token ref count.
*/
AWS_S3_API
struct aws_s3_meta_request_resume_token *aws_s3_meta_request_resume_token_acquire(
struct aws_s3_meta_request_resume_token *resume_token);
/*
* Decrement resume token ref count.
*/
AWS_S3_API
struct aws_s3_meta_request_resume_token *aws_s3_meta_request_resume_token_release(
struct aws_s3_meta_request_resume_token *resume_token);
/*
* Type of resume token.
*/
AWS_S3_API
enum aws_s3_meta_request_type aws_s3_meta_request_resume_token_type(
struct aws_s3_meta_request_resume_token *resume_token);
/*
* Part size associated with operation.
*/
AWS_S3_API
uint64_t aws_s3_meta_request_resume_token_part_size(struct aws_s3_meta_request_resume_token *resume_token);
/*
* Total num parts associated with operation.
*/
AWS_S3_API
size_t aws_s3_meta_request_resume_token_total_num_parts(struct aws_s3_meta_request_resume_token *resume_token);
/*
* Num parts completed.
*/
AWS_S3_API
size_t aws_s3_meta_request_resume_token_num_parts_completed(struct aws_s3_meta_request_resume_token *resume_token);
/*
* Upload id associated with operation.
* Only valid for tokens returned from upload operation. For all other operations
* this will return empty.
*/
AWS_S3_API
struct aws_byte_cursor aws_s3_meta_request_resume_token_upload_id(
struct aws_s3_meta_request_resume_token *resume_token);
/**
* Add a reference, keeping this object alive.
* The reference must be released when you are done with it, or it's memory will never be cleaned up.
* You must not pass in NULL.
* Always returns the same pointer that was passed in.
*/
AWS_S3_API
struct aws_s3_meta_request *aws_s3_meta_request_acquire(struct aws_s3_meta_request *meta_request);
/**
* Release a reference.
* When the reference count drops to 0, this object will be cleaned up.
* It's OK to pass in NULL (nothing happens).
* Always returns NULL.
*/
AWS_S3_API
struct aws_s3_meta_request *aws_s3_meta_request_release(struct aws_s3_meta_request *meta_request);
/**
* Initialize the configuration for a default S3 signing.
*/
AWS_S3_API
void aws_s3_init_default_signing_config(
struct aws_signing_config_aws *signing_config,
const struct aws_byte_cursor region,
struct aws_credentials_provider *credentials_provider);
/**
* Return operation name for aws_s3_request_type,
* or empty string if the type doesn't map to an actual operation.
* For example:
* AWS_S3_REQUEST_TYPE_HEAD_OBJECT -> "HeadObject"
* AWS_S3_REQUEST_TYPE_UNKNOWN -> ""
* AWS_S3_REQUEST_TYPE_MAX -> ""
*/
AWS_S3_API
const char *aws_s3_request_type_operation_name(enum aws_s3_request_type type);
/**
* Add a reference, keeping this object alive.
* The reference must be released when you are done with it, or it's memory will never be cleaned up.
* Always returns the same pointer that was passed in.
*/
AWS_S3_API
struct aws_s3_request_metrics *aws_s3_request_metrics_acquire(struct aws_s3_request_metrics *metrics);
/**
* Release a reference.
* When the reference count drops to 0, this object will be cleaned up.
* It's OK to pass in NULL (nothing happens).
* Always returns NULL.
*/
AWS_S3_API
struct aws_s3_request_metrics *aws_s3_request_metrics_release(struct aws_s3_request_metrics *metrics);
/************************************* Getters for s3 request metrics ************************************************/
/**
* Get the request ID from aws_s3_request_metrics.
* If unavailable, AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised.
* If available, out_request_id will be set to a string. Be warned this string's lifetime is tied to the metrics
* object.
**/
AWS_S3_API
int aws_s3_request_metrics_get_request_id(
const struct aws_s3_request_metrics *metrics,
const struct aws_string **out_request_id);
/* Get the start time from aws_s3_request_metrics, which is when S3 client prepare the request to be sent. Always
* available. Timestamp are from `aws_high_res_clock_get_ticks` */
AWS_S3_API
void aws_s3_request_metrics_get_start_timestamp_ns(
const struct aws_s3_request_metrics *metrics,
uint64_t *out_start_time);
/* Get the end time from aws_s3_request_metrics. Always available */
AWS_S3_API
void aws_s3_request_metrics_get_end_timestamp_ns(const struct aws_s3_request_metrics *metrics, uint64_t *out_end_time);
/* Get the total duration time from aws_s3_request_metrics. Always available */
AWS_S3_API
void aws_s3_request_metrics_get_total_duration_ns(
const struct aws_s3_request_metrics *metrics,
uint64_t *out_total_duration);
/* Get the time stamp when the request started to be encoded. Timestamps are from `aws_high_res_clock_get_ticks`
* AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if the request ended before it gets sent. */
AWS_S3_API
int aws_s3_request_metrics_get_send_start_timestamp_ns(
const struct aws_s3_request_metrics *metrics,
uint64_t *out_send_start_time);
/* Get the time stamp when the request finished to be encoded. Timestamps are from `aws_high_res_clock_get_ticks`
* AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if data not available. */
AWS_S3_API
int aws_s3_request_metrics_get_send_end_timestamp_ns(
const struct aws_s3_request_metrics *metrics,
uint64_t *out_send_end_time);
/* The time duration for the request from start encoding to finish encoding (send_end_timestamp_ns -
* send_start_timestamp_ns).
* AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if data not available. */
AWS_S3_API
int aws_s3_request_metrics_get_sending_duration_ns(
const struct aws_s3_request_metrics *metrics,
uint64_t *out_sending_duration);
/* Get the time stamp when the response started to be received from the network channel. Timestamps are from
* `aws_high_res_clock_get_ticks` AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if data not available. */
AWS_S3_API
int aws_s3_request_metrics_get_receive_start_timestamp_ns(
const struct aws_s3_request_metrics *metrics,
uint64_t *out_receive_start_time);
/* Get the time stamp when the response finished to be received from the network channel. Timestamps are from
* `aws_high_res_clock_get_ticks` AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if data not available. */
AWS_S3_API
int aws_s3_request_metrics_get_receive_end_timestamp_ns(
const struct aws_s3_request_metrics *metrics,
uint64_t *out_receive_end_time);
/* The time duration for the request from start receiving to finish receiving (receive_end_timestamp_ns -
* receive_start_timestamp_ns).
* AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if data not available. */
AWS_S3_API
int aws_s3_request_metrics_get_receiving_duration_ns(
const struct aws_s3_request_metrics *metrics,
uint64_t *out_receiving_duration);
/* Get the response status code for the request. AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if data not
* available. */
AWS_S3_API
int aws_s3_request_metrics_get_response_status_code(
const struct aws_s3_request_metrics *metrics,
int *out_response_status);
/* Get the HTTP Headers of the response received for the request. AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised
* if data not available. */
AWS_S3_API
int aws_s3_request_metrics_get_response_headers(
const struct aws_s3_request_metrics *metrics,
struct aws_http_headers **out_response_headers);
/**
* Get the path and query of the request.
* If unavailable, AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised.
* If available, out_request_path_query will be set to a string. Be warned this string's lifetime is tied to the metrics
* object.
*/
AWS_S3_API
void aws_s3_request_metrics_get_request_path_query(
const struct aws_s3_request_metrics *metrics,
const struct aws_string **out_request_path_query);
/**
* Get the host_address of the request.
* If unavailable, AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised.
* If available, out_host_address will be set to a string. Be warned this string's lifetime is tied to the metrics
* object.
*/
AWS_S3_API
void aws_s3_request_metrics_get_host_address(
const struct aws_s3_request_metrics *metrics,
const struct aws_string **out_host_address);
/**
* Get the IP address of the request connected to.
* If unavailable, AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised.
* If available, out_ip_address will be set to a string. Be warned this string's lifetime is tied to the metrics object.
*/
AWS_S3_API
int aws_s3_request_metrics_get_ip_address(
const struct aws_s3_request_metrics *metrics,
const struct aws_string **out_ip_address);
/* Get the id of connection that request was made from. AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if data
* not available */
AWS_S3_API
int aws_s3_request_metrics_get_connection_id(const struct aws_s3_request_metrics *metrics, size_t *out_connection_id);
/* Get the thread ID of the thread that request was made from. AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised if
* data not available */
AWS_S3_API
int aws_s3_request_metrics_get_thread_id(const struct aws_s3_request_metrics *metrics, aws_thread_id_t *out_thread_id);
/* Get the stream-id, which is the idex when the stream was activated. AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be
* raised if data not available */
AWS_S3_API
int aws_s3_request_metrics_get_request_stream_id(const struct aws_s3_request_metrics *metrics, uint32_t *out_stream_id);
/**
* Get the S3 operation name of the request (e.g. "HeadObject").
* If unavailable, AWS_ERROR_S3_METRIC_DATA_NOT_AVAILABLE will be raised.
* If available, out_operation_name will be set to a string.
* Be warned this string's lifetime is tied to the metrics object.
*/
AWS_S3_API
int aws_s3_request_metrics_get_operation_name(
const struct aws_s3_request_metrics *metrics,
const struct aws_string **out_operation_name);
/* Get the request type from request metrics.
* If you just need a string, aws_s3_request_metrics_get_operation_name() is more reliable. */
AWS_S3_API
void aws_s3_request_metrics_get_request_type(
const struct aws_s3_request_metrics *metrics,
enum aws_s3_request_type *out_request_type);
/* Get the AWS CRT error code from request metrics. */
AWS_S3_API
int aws_s3_request_metrics_get_error_code(const struct aws_s3_request_metrics *metrics);
AWS_EXTERN_C_END
AWS_POP_SANE_WARNING_LEVEL
#endif /* AWS_S3_CLIENT_H */