Help Center/ Object Storage Service/ SDK Reference/ C/ Bucket APIs (SDK for C)/ Other APIs (SDK for C)/ Using a Temporary URL for Authorized Access (SDK for C)
Updated on 2026-08-03 GMT+08:00

Using a Temporary URL for Authorized Access (SDK for C)

If you have any questions during development, post them on the Issues page of GitHub.

Function

This API creates a temporary URL to grant temporary permissions for operating OBS. This URL contains the information about the AK and SK, request method, and related parameters. You need to specify a validity period for the URL during the creation. To create such a URL, you need to use the temp_auth_configure structure.

The temp_auth_configure structure exists in the obs_options structure. This method is applicable to each C SDK API.

Parameter

Type

Mandatory (Yes/No)

Description

expires

long long int

Yes

Explanation:

Validity period of the generated temporary URL.

Restrictions:

None

Value range:

The value is a positive integer, in seconds. The recommended value range is [1, 604800] (1 second to 7 days). A value of 0 or any negative number is invalid.

Default value:

None

temp_auth_callback

void (*Table 1)(char *, uint64_t, char *, uint64_t, void *)

Yes

Explanation:

Callback function, which is used to return the generated temporary URL and actual request headers.

Restrictions:

None

Value range:

None

Default value:

None

callback_data

void *

No

Explanation:

Pointer to custom callback data, which will be transparently transmitted to the user in the callback function.

Restrictions:

None

Value range:

None

Default value:

NULL

Table 1 temp_auth_callback

Parameter

Type

Mandatory (Yes/No)

Description

temp_auth_url

char *

Yes

Explanation:

Generated temporary URL.

Restrictions:

None

Value range:

None

Default value:

None

temp_auth_url_len

uint64_t

Yes

Explanation:

Length of the temporary URL, in bytes.

Restrictions:

None

Value range:

None

Default value:

None

temp_auth_headers

char *

Yes

Explanation:

Request headers used to generate a temporary URL.

Restrictions:

None

Value range:

None

Default value:

None

temp_auth_headers_len

uint64_t

Yes

Explanation:

Length of the actual request headers, in bytes.

Restrictions:

None

Value range:

None

Default value:

None

callback_data

void *

Yes

Explanation:

Pointer to the custom callback data.

Restrictions:

None

Value range:

None

Default value:

None

Restrictions

  • The mapping between OBS regions and endpoints must comply with what is listed in Regions and Endpoints.
  • If a CORS or signature mismatch error occurs, troubleshoot the issue as follows:
    1. If CORS is not configured, you need to configure CORS rules on OBS Console. For details, see Configuring CORS.
    2. If the signatures do not match, check whether signature parameters are missing or invalid. For details, see Authentication of Signature in a URL. For example, during an object upload, the backend uses Content-Type to calculate the signature and generate a temporary URL, but if Content-Type is not set or is set to an invalid value when the frontend uses that URL, a CORS error occurs. To resolve this issue, ensure Content-Type remains consistent at the frontend and backend.

Method

void (*temp_auth_callback)(char *temp_auth_url, uint64_t temp_auth_url_len, char *temp_auth_headers,
        uint64_t temp_auth_headers_len, void *callback_data);

To access OBS using a temporary URL generated by the OBS SDK for C, perform the following steps:

  1. Call any interface in the SDK to generate a temporary URL and headers based on the following code example.
  2. Use any HTTP library to make an HTTP/HTTPS request to OBS.

The following code examples use a temporary URL to create a bucket or upload, download, list, or delete objects.

Code Examples: Generating a Temporary URL for Creating a Bucket

This example generates a temporary URL for creating a bucket.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include "eSDKOBS.h"
#include <stdio.h>
#define MAX_TEMP_URL_LEN 1024
#define MAX_HEADER_LEN 1024
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data);
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data); 
typedef struct __tempAuthResult
{
    char tmpAuthUrl[MAX_TEMP_URL_LEN];
    char actualHeaders[MAX_HEADER_LEN];
}tempAuthResult;
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData);

int main()
{
    // The following code shows how to generate a URL for creating a bucket:
    // Call the obs_initialize method at the program entry to initialize global resources such as the network and memory.
    obs_status ret_status = obs_initialize(OBS_INIT_ALL);
    if (OBS_STATUS_OK != ret_status)
    {
        printf("obs_initialize failed(%s).\n", obs_get_status_name(ret_status));
        return -1;
    }
    obs_options options;
    // Create and initialize options, including the access domain name (host_name), access keys (access_key_id and access_key_secret), bucket name (bucket_name), and bucket storage class (storage_class).
    init_obs_options(&options);
    // Enter the endpoint corresponding to the bucket for host_name. CN-Hong Kong is used here as an example. Replace it with the one in your actual situation.
    options.bucket_options.host_name = "obs.ap-southeast-1.myhuaweicloud.com";
    // Hard-coded or plaintext AK and SK are risky. For security purposes, encrypt your AK and SK and store them in the configuration file or environment variables.
    // In this example, the AK and SK are stored in environment variables for identity authentication. Before running the code in this example, configure local environment variables ACCESS_KEY_ID and SECRET_ACCESS_KEY.
    options.bucket_options.access_key = getenv("ACCESS_KEY_ID");
    options.bucket_options.secret_access_key = getenv("SECRET_ACCESS_KEY");
    // Check whether environment variables are set.
    if (!options.bucket_options.access_key || !options.bucket_options.secret_access_key) {
        printf("ERROR: ACCESS_KEY_ID and SECRET_ACCESS_KEY environment variables must be set.\n");
        obs_deinitialize();
        return -1;
    }
    // Specify the bucket name, for example, example-bucket-name.
    char * bucket_name = "example-bucket-name";
    options.bucket_options.bucket_name = bucket_name;
    temp_auth_configure tempauth;
    tempAuthResult  ptrResult;
    memset(&ptrResult, 0, sizeof(tempAuthResult));
    //Callback data
    tempauth.callback_data = (void *)(&ptrResult);
    // Valid time (unit: second)
    tempauth.expires = 10;
    // The callback function returns the generated temporary URL.
    tempauth.temp_auth_callback = &tempAuthCallBack_getResult;
    options.temp_auth = &tempauth;
    // Assign values to the callback function.
    obs_response_handler response_handler =
    {
        &response_properties_callback,
        &response_complete_callback
    };
    ret_status = OBS_STATUS_BUTT;
    // Call the interface.
    create_bucket(&options, OBS_CANNED_ACL_PRIVATE, NULL, &response_handler, &ret_status);
    // Check whether the request is successful.
    if (ret_status == OBS_STATUS_OK) {
        printf("the temporary signature url of create bucket generated successfully. \n"
            "the temporary signature url is %s. \n"
            "the actualHeaders are %s. \n", ptrResult.tmpAuthUrl, ptrResult.actualHeaders);
    }
    else
    {
        printf(" the temporary signature url of create bucket generation failed(%s).\n", obs_get_status_name(ret_status));
    }
    // Release the allocated global resources.
    obs_deinitialize();
}
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data)
{
    if (properties == NULL)
    {
        printf("error! obs_response_properties is null!");
        return OBS_STATUS_OK;      
    }
    // Print the response.
#define print_nonnull(name, field)                                 \
    do {                                                           \
        if (properties-> field) {                                  \
            printf("%s: %s\n", name, properties->field);          \
        }                                                          \
    } while (0)
    print_nonnull("request_id", request_id);
    print_nonnull("request_id2", request_id2);
    print_nonnull("content_type", content_type);
    if (properties->content_length) {
        printf("content_length: %llu\n", properties->content_length);
    }
    print_nonnull("server", server);
    print_nonnull("ETag", etag);
    print_nonnull("expiration", expiration);
    print_nonnull("website_redirect_location", website_redirect_location);
    print_nonnull("version_id", version_id);
    print_nonnull("allow_origin", allow_origin);
    print_nonnull("allow_headers", allow_headers);
    print_nonnull("max_age", max_age);
    print_nonnull("allow_methods", allow_methods);
    print_nonnull("expose_headers", expose_headers);
    print_nonnull("storage_class", storage_class);
    print_nonnull("server_side_encryption", server_side_encryption);
    print_nonnull("kms_key_id", kms_key_id);
    print_nonnull("customer_algorithm", customer_algorithm);
    print_nonnull("customer_key_md5", customer_key_md5);
    print_nonnull("bucket_location", bucket_location);
    print_nonnull("obs_version", obs_version);
    print_nonnull("restore", restore);
    print_nonnull("obs_object_type", obs_object_type);
    print_nonnull("obs_next_append_position", obs_next_append_position);
    print_nonnull("obs_head_epid", obs_head_epid);
    print_nonnull("reserved_indicator", reserved_indicator);
    int i;
    for (i = 0; i < properties->meta_data_count; i++) {
        printf("x-obs-meta-%s: %s\n", properties->meta_data[i].name,
            properties->meta_data[i].value);
    }
    return OBS_STATUS_OK;
}
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data)
{
    if (callback_data) {
        obs_status *ret_status = (obs_status *)callback_data;
        *ret_status = status;
    }
    else {
        printf("Callback_data is NULL");
    }
    if (error && error->message) {
        printf("Error Message: \n   %s\n", error->message);
    }
    if (error && error->resource) {
        printf("Error Resource: \n  %s\n", error->resource);
    }
    if (error && error->further_details) {
        printf("Error further_details: \n   %s\n", error->further_details);
    }
    if (error && error->extra_details_count) {
        int i;
        for (i = 0; i < error->extra_details_count; i++) {
            printf("Error Extra Detail(%d):\n   %s:%s\n", i, error->extra_details[i].name,
                error->extra_details[i].value);
        }
    }
    if (error && error->error_headers_count) {
        int i;
        for (i = 0; i < error->error_headers_count; i++) {
            const char *errorHeader = error->error_headers[i];
            printf("Error Headers(%d):\n    %s\n", i, errorHeader == NULL ? "NULL Header" : errorHeader);
        }
    }
}
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData)
{
    tempAuthResult * ptrResult = (tempAuthResult *)callbackData;
    if (tempAuthUrlLen >= MAX_TEMP_URL_LEN) {
        printf("WARNING: temp URL is too long (%llu >= %d), truncated.\n",
            (unsigned long long)tempAuthUrlLen, MAX_TEMP_URL_LEN);
    }
    if (tempAuthActualHeadersLen >= MAX_HEADER_LEN) {
        printf("WARNING: temp headers are too long (%llu >= %d), truncated.\n",
            (unsigned long long)tempAuthActualHeadersLen, MAX_HEADER_LEN);
    }
    errno_t ret = strcpy_s(ptrResult->tmpAuthUrl, MAX_TEMP_URL_LEN, tempAuthUrl);
    if (ret != 0) {
        printf("ERROR: failed to copy temp auth URL.\n");
    }
    ret = strcpy_s(ptrResult->actualHeaders, MAX_HEADER_LEN, tempAuthActualHeaders);
    if (ret != 0) {
        printf("ERROR: failed to copy temp auth headers.\n");
    }
}

Code Examples: Generating a Temporary URL for Uploading an Object

This example generates a temporary URL for uploading an object.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "eSDKOBS.h"
#include <stdio.h>
#define MAX_TEMP_URL_LEN 1024
#define MAX_HEADER_LEN 1024
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data);
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data); 
typedef struct __tempAuthResult
{
    char tmpAuthUrl[MAX_TEMP_URL_LEN];
    char actualHeaders[MAX_HEADER_LEN];
}tempAuthResult;
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData);
int main()
{
    // The following code shows how to generate a URL for uploading an object:
    // Call the obs_initialize method at the program entry to initialize global resources such as the network and memory.
    obs_status ret_status = obs_initialize(OBS_INIT_ALL);
    if (OBS_STATUS_OK != ret_status)
    {
        printf("obs_initialize failed(%s).\n", obs_get_status_name(ret_status));
        return -1;
    }
    obs_options options;
    // Create and initialize options, including the access domain name (host_name), access keys (access_key_id and access_key_secret), bucket name (bucket_name), and bucket storage class (storage_class).
    init_obs_options(&options);
    // Enter the endpoint corresponding to the bucket for host_name. CN-Hong Kong is used here as an example. Replace it with the one in your actual situation.
    options.bucket_options.host_name = "obs.ap-southeast-1.myhuaweicloud.com";
    // Hard-coded or plaintext AK and SK are risky. For security purposes, encrypt your AK and SK and store them in the configuration file or environment variables.
    // In this example, the AK and SK are stored in environment variables for identity authentication. Before running the code in this example, configure local environment variables ACCESS_KEY_ID and SECRET_ACCESS_KEY.
    options.bucket_options.access_key = getenv("ACCESS_KEY_ID");
    options.bucket_options.secret_access_key = getenv("SECRET_ACCESS_KEY");
    // Check whether environment variables are set.
    if (!options.bucket_options.access_key || !options.bucket_options.secret_access_key) {
        printf("ERROR: ACCESS_KEY_ID and SECRET_ACCESS_KEY environment variables must be set.\n");
        obs_deinitialize();
        return -1;
    }
    // Specify the bucket name, for example, example-bucket-name.
    char * bucket_name = "example-bucket-name";
    options.bucket_options.bucket_name = bucket_name;
    temp_auth_configure tempauth;
    tempAuthResult  ptrResult;
    memset(&ptrResult, 0, sizeof(tempAuthResult));
    //Callback data
    tempauth.callback_data = (void *)(&ptrResult);
    // Valid time (unit: second)
    tempauth.expires = 10;
    // The callback function returns the generated temporary URL.
    tempauth.temp_auth_callback = &tempAuthCallBack_getResult;
    options.temp_auth = &tempauth;
    // Assign values to the callback function.
    obs_response_handler response_handler =
    {
        &response_properties_callback,
        &response_complete_callback
    };
    ret_status = OBS_STATUS_BUTT;
    char* key = "example-object-key";
    obs_put_object_handler putobjectHandler =
    {
        response_handler,
        NULL
    };
    // Initialize the put_properties structure.
    obs_put_properties put_properties;
    init_put_properties(&put_properties);
    // Call the interface.
    put_object(&options, key, 0, &put_properties, 0, &putobjectHandler, &ret_status);
    // Check whether the request is successful.
    if (ret_status == OBS_STATUS_OK) {
        printf("the temporary signature url of put object generated successfully. \n"
            "the temporary signature url is %s. \n"
            "the actualHeaders are %s. \n", ptrResult.tmpAuthUrl, ptrResult.actualHeaders);
    }
    else
    {
        printf(" the temporary signature url of put object generation failed(%s).\n", obs_get_status_name(ret_status));
    }
    // Release the allocated global resources.
    obs_deinitialize();
}
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data)
{
    if (properties == NULL)
    {
        printf("error! obs_response_properties is null!");
        return OBS_STATUS_OK;      
    }
    // Print the response.
#define print_nonnull(name, field)                                 \
    do {                                                           \
        if (properties-> field) {                                  \
            printf("%s: %s\n", name, properties->field);          \
        }                                                          \
    } while (0)
    print_nonnull("request_id", request_id);
    print_nonnull("request_id2", request_id2);
    print_nonnull("content_type", content_type);
    if (properties->content_length) {
        printf("content_length: %llu\n", properties->content_length);
    }
    print_nonnull("server", server);
    print_nonnull("ETag", etag);
    print_nonnull("expiration", expiration);
    print_nonnull("website_redirect_location", website_redirect_location);
    print_nonnull("version_id", version_id);
    print_nonnull("allow_origin", allow_origin);
    print_nonnull("allow_headers", allow_headers);
    print_nonnull("max_age", max_age);
    print_nonnull("allow_methods", allow_methods);
    print_nonnull("expose_headers", expose_headers);
    print_nonnull("storage_class", storage_class);
    print_nonnull("server_side_encryption", server_side_encryption);
    print_nonnull("kms_key_id", kms_key_id);
    print_nonnull("customer_algorithm", customer_algorithm);
    print_nonnull("customer_key_md5", customer_key_md5);
    print_nonnull("bucket_location", bucket_location);
    print_nonnull("obs_version", obs_version);
    print_nonnull("restore", restore);
    print_nonnull("obs_object_type", obs_object_type);
    print_nonnull("obs_next_append_position", obs_next_append_position);
    print_nonnull("obs_head_epid", obs_head_epid);
    print_nonnull("reserved_indicator", reserved_indicator);
    int i;
    for (i = 0; i < properties->meta_data_count; i++) {
        printf("x-obs-meta-%s: %s\n", properties->meta_data[i].name,
            properties->meta_data[i].value);
    }
    return OBS_STATUS_OK;
}
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data)
{
    if (callback_data) {
        obs_status *ret_status = (obs_status *)callback_data;
        *ret_status = status;
    }
    else {
        printf("Callback_data is NULL");
    }
    if (error && error->message) {
        printf("Error Message: \n   %s\n", error->message);
    }
    if (error && error->resource) {
        printf("Error Resource: \n  %s\n", error->resource);
    }
    if (error && error->further_details) {
        printf("Error further_details: \n   %s\n", error->further_details);
    }
    if (error && error->extra_details_count) {
        int i;
        for (i = 0; i < error->extra_details_count; i++) {
            printf("Error Extra Detail(%d):\n   %s:%s\n", i, error->extra_details[i].name,
                error->extra_details[i].value);
        }
    }
    if (error && error->error_headers_count) {
        int i;
        for (i = 0; i < error->error_headers_count; i++) {
            const char *errorHeader = error->error_headers[i];
            printf("Error Headers(%d):\n    %s\n", i, errorHeader == NULL ? "NULL Header" : errorHeader);
        }
    }
}
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData)
{
    tempAuthResult * ptrResult = (tempAuthResult *)callbackData;
    errno_t ret = strcpy_s(ptrResult->tmpAuthUrl, MAX_TEMP_URL_LEN, tempAuthUrl);
    if (ret != 0) { printf("ERROR: failed to copy temp auth URL.\n"); }
    ret = strcpy_s(ptrResult->actualHeaders, MAX_HEADER_LEN, tempAuthActualHeaders);
    if (ret != 0) { printf("ERROR: failed to copy temp auth headers.\n"); }
}

Code Examples: Generating a Temporary URL for Downloading an Object

This example generates a temporary URL for downloading an object.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include "eSDKOBS.h"
#include <stdio.h>
#define MAX_TEMP_URL_LEN 1024
#define MAX_HEADER_LEN 1024
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data);
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data); 
typedef struct __tempAuthResult
{
    char tmpAuthUrl[MAX_TEMP_URL_LEN];
    char actualHeaders[MAX_HEADER_LEN];
}tempAuthResult;
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData);
int main()
{
    // The following code shows how to generate a URL for downloading an object:
    // Call the obs_initialize method at the program entry to initialize global resources such as the network and memory.
    obs_status ret_status = obs_initialize(OBS_INIT_ALL);
    if (OBS_STATUS_OK != ret_status)
    {
        printf("obs_initialize failed(%s).\n", obs_get_status_name(ret_status));
        return -1;
    }
    obs_options options;
    // Create and initialize options, including the access domain name (host_name), access keys (access_key_id and access_key_secret), bucket name (bucket_name), and bucket storage class (storage_class).
    init_obs_options(&options);
    // Enter the endpoint corresponding to the bucket for host_name. CN-Hong Kong is used here as an example. Replace it with the one in your actual situation.
    options.bucket_options.host_name = "obs.ap-southeast-1.myhuaweicloud.com";
    // Hard-coded or plaintext AK and SK are risky. For security purposes, encrypt your AK and SK and store them in the configuration file or environment variables.
    // In this example, the AK and SK are stored in environment variables for identity authentication. Before running the code in this example, configure local environment variables ACCESS_KEY_ID and SECRET_ACCESS_KEY.
    options.bucket_options.access_key = getenv("ACCESS_KEY_ID");
    options.bucket_options.secret_access_key = getenv("SECRET_ACCESS_KEY");
    // Check whether environment variables are set.
    if (!options.bucket_options.access_key || !options.bucket_options.secret_access_key) {
        printf("ERROR: ACCESS_KEY_ID and SECRET_ACCESS_KEY environment variables must be set.\n");
        obs_deinitialize();
        return -1;
    }
    // Specify the bucket name, for example, example-bucket-name.
    char * bucket_name = "example-bucket-name";
    options.bucket_options.bucket_name = bucket_name;
    temp_auth_configure tempauth;
    tempAuthResult  ptrResult;
    memset(&ptrResult, 0, sizeof(tempAuthResult));
    //Callback data
    tempauth.callback_data = (void *)(&ptrResult);
    // Valid time (unit: second)
    tempauth.expires = 10;
    // The callback function returns the generated temporary URL.
    tempauth.temp_auth_callback = &tempAuthCallBack_getResult;
    options.temp_auth = &tempauth;
    // Assign values to the callback function.
    obs_response_handler response_handler =
    {
        &response_properties_callback,
        &response_complete_callback
    };
    ret_status = OBS_STATUS_BUTT;
    char* key = "example-object-key";
    char* versionid = NULL;
    // Downloaded object information
    obs_object_info object_info;
    memset(&object_info, 0, sizeof(obs_object_info));
    object_info.key = key;
    object_info.version_id = versionid;
    obs_get_object_handler getobjectHandler =
    {
        response_handler,
        NULL
    };
    // Initialize the put_properties structure.
    obs_put_properties put_properties;
    init_put_properties(&put_properties);
    // Call the interface.
    get_object(&options, &object_info, 0, 0, &getobjectHandler, &ret_status);
    // Check whether the request is successful.
    if (ret_status == OBS_STATUS_OK) {
        printf("the temporary signature url of get object generated successfully. \n"
            "the temporary signature url is %s. \n"
            "the actualHeaders are %s. \n", ptrResult.tmpAuthUrl, ptrResult.actualHeaders);
    }
    else
    {
        printf(" the temporary signature url of get object generation failed(%s).\n", obs_get_status_name(ret_status));
    }
    // Release the allocated global resources.
    obs_deinitialize();
}
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data)
{
    if (properties == NULL)
    {
        printf("error! obs_response_properties is null!");
        return OBS_STATUS_OK;      
    }
    // Print the response.
#define print_nonnull(name, field)                                 \
    do {                                                           \
        if (properties-> field) {                                  \
            printf("%s: %s\n", name, properties->field);          \
        }                                                          \
    } while (0)
    print_nonnull("request_id", request_id);
    print_nonnull("request_id2", request_id2);
    print_nonnull("content_type", content_type);
    if (properties->content_length) {
        printf("content_length: %llu\n", properties->content_length);
    }
    print_nonnull("server", server);
    print_nonnull("ETag", etag);
    print_nonnull("expiration", expiration);
    print_nonnull("website_redirect_location", website_redirect_location);
    print_nonnull("version_id", version_id);
    print_nonnull("allow_origin", allow_origin);
    print_nonnull("allow_headers", allow_headers);
    print_nonnull("max_age", max_age);
    print_nonnull("allow_methods", allow_methods);
    print_nonnull("expose_headers", expose_headers);
    print_nonnull("storage_class", storage_class);
    print_nonnull("server_side_encryption", server_side_encryption);
    print_nonnull("kms_key_id", kms_key_id);
    print_nonnull("customer_algorithm", customer_algorithm);
    print_nonnull("customer_key_md5", customer_key_md5);
    print_nonnull("bucket_location", bucket_location);
    print_nonnull("obs_version", obs_version);
    print_nonnull("restore", restore);
    print_nonnull("obs_object_type", obs_object_type);
    print_nonnull("obs_next_append_position", obs_next_append_position);
    print_nonnull("obs_head_epid", obs_head_epid);
    print_nonnull("reserved_indicator", reserved_indicator);
    int i;
    for (i = 0; i < properties->meta_data_count; i++) {
        printf("x-obs-meta-%s: %s\n", properties->meta_data[i].name,
            properties->meta_data[i].value);
    }
    return OBS_STATUS_OK;
}
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data)
{
    if (callback_data) {
        obs_status *ret_status = (obs_status *)callback_data;
        *ret_status = status;
    }
    else {
        printf("Callback_data is NULL");
    }
    if (error && error->message) {
        printf("Error Message: \n   %s\n", error->message);
    }
    if (error && error->resource) {
        printf("Error Resource: \n  %s\n", error->resource);
    }
    if (error && error->further_details) {
        printf("Error further_details: \n   %s\n", error->further_details);
    }
    if (error && error->extra_details_count) {
        int i;
        for (i = 0; i < error->extra_details_count; i++) {
            printf("Error Extra Detail(%d):\n   %s:%s\n", i, error->extra_details[i].name,
                error->extra_details[i].value);
        }
    }
    if (error && error->error_headers_count) {
        int i;
        for (i = 0; i < error->error_headers_count; i++) {
            const char *errorHeader = error->error_headers[i];
            printf("Error Headers(%d):\n    %s\n", i, errorHeader == NULL ? "NULL Header" : errorHeader);
        }
    }
}
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData)
{
    tempAuthResult * ptrResult = (tempAuthResult *)callbackData;
    errno_t ret = strcpy_s(ptrResult->tmpAuthUrl, MAX_TEMP_URL_LEN, tempAuthUrl);
    if (ret != 0) { printf("ERROR: failed to copy temp auth URL.\n"); }
    ret = strcpy_s(ptrResult->actualHeaders, MAX_HEADER_LEN, tempAuthActualHeaders);
    if (ret != 0) { printf("ERROR: failed to copy temp auth headers.\n"); }
}

Code Examples: Generating a Temporary URL for Listing Objects

This example generates a temporary URL for listing objects.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include "eSDKOBS.h"
#include <stdio.h>
#define MAX_TEMP_URL_LEN 1024
#define MAX_HEADER_LEN 1024
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data);
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data); 
typedef struct __tempAuthResult
{
    char tmpAuthUrl[MAX_TEMP_URL_LEN];
    char actualHeaders[MAX_HEADER_LEN];
}tempAuthResult;
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData);
int main()
{
    // The following code shows how to generate a URL for listing objects:
    // Call the obs_initialize method at the program entry to initialize global resources such as the network and memory.
    obs_status ret_status = obs_initialize(OBS_INIT_ALL);
    if (OBS_STATUS_OK != ret_status)
    {
        printf("obs_initialize failed(%s).\n", obs_get_status_name(ret_status));
        return -1;
    }
    obs_options options;
    // Create and initialize options, including the access domain name (host_name), access keys (access_key_id and access_key_secret), bucket name (bucket_name), and bucket storage class (storage_class).
    init_obs_options(&options);
    // Enter the endpoint corresponding to the bucket for host_name. CN-Hong Kong is used here as an example. Replace it with the one in your actual situation.
    options.bucket_options.host_name = "obs.ap-southeast-1.myhuaweicloud.com";
    // Hard-coded or plaintext AK and SK are risky. For security purposes, encrypt your AK and SK and store them in the configuration file or environment variables.
    // In this example, the AK and SK are stored in environment variables for identity authentication. Before running the code in this example, configure local environment variables ACCESS_KEY_ID and SECRET_ACCESS_KEY.
    options.bucket_options.access_key = getenv("ACCESS_KEY_ID");
    options.bucket_options.secret_access_key = getenv("SECRET_ACCESS_KEY");
    // Check whether environment variables are set.
    if (!options.bucket_options.access_key || !options.bucket_options.secret_access_key) {
        printf("ERROR: ACCESS_KEY_ID and SECRET_ACCESS_KEY environment variables must be set.\n");
        obs_deinitialize();
        return -1;
    }
    // Specify the bucket name, for example, example-bucket-name.
    char * bucket_name = "example-bucket-name";
    options.bucket_options.bucket_name = bucket_name;
    temp_auth_configure tempauth;
    tempAuthResult  ptrResult;
    memset(&ptrResult, 0, sizeof(tempAuthResult));
    //Callback data
    tempauth.callback_data = (void *)(&ptrResult);
    // Valid time (unit: second)
    tempauth.expires = 10;
    // The callback function returns the generated temporary URL.
    tempauth.temp_auth_callback = &tempAuthCallBack_getResult;
    options.temp_auth = &tempauth;
    // Assign values to the callback function.
    obs_response_handler response_handler =
    {
        &response_properties_callback,
        &response_complete_callback
    };
    ret_status = OBS_STATUS_BUTT;
    char* prefix = "example-prefix";
    char* next_marker = "example-next-marker";
    char* delimiter = "/";
    //Maximum number of objects that can be listed
    int maxkeys = 100;
    obs_list_objects_handler list_bucket_objects_handler =
    {
        response_handler,
        NULL
    };
    list_bucket_objects(&options, prefix, next_marker, delimiter, maxkeys,
        &list_bucket_objects_handler, &ret_status);
    // Check whether the request is successful.
    if (ret_status == OBS_STATUS_OK) {
        printf("the temporary signature url of list objects generated successfully. \n"
            "the temporary signature url is %s. \n"
            "the actualHeaders are %s. \n", ptrResult.tmpAuthUrl, ptrResult.actualHeaders);
    }
    else
    {
        printf(" the temporary signature url of list objects generation failed(%s).\n", obs_get_status_name(ret_status));
    }
    // Release the allocated global resources.
    obs_deinitialize();
}
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data)
{
    if (properties == NULL)
    {
        printf("error! obs_response_properties is null!");
        return OBS_STATUS_OK;      
    }
    // Print the response.
#define print_nonnull(name, field)                                 \
    do {                                                           \
        if (properties-> field) {                                  \
            printf("%s: %s\n", name, properties->field);          \
        }                                                          \
    } while (0)
    print_nonnull("request_id", request_id);
    print_nonnull("request_id2", request_id2);
    print_nonnull("content_type", content_type);
    if (properties->content_length) {
        printf("content_length: %llu\n", properties->content_length);
    }
    print_nonnull("server", server);
    print_nonnull("ETag", etag);
    print_nonnull("expiration", expiration);
    print_nonnull("website_redirect_location", website_redirect_location);
    print_nonnull("version_id", version_id);
    print_nonnull("allow_origin", allow_origin);
    print_nonnull("allow_headers", allow_headers);
    print_nonnull("max_age", max_age);
    print_nonnull("allow_methods", allow_methods);
    print_nonnull("expose_headers", expose_headers);
    print_nonnull("storage_class", storage_class);
    print_nonnull("server_side_encryption", server_side_encryption);
    print_nonnull("kms_key_id", kms_key_id);
    print_nonnull("customer_algorithm", customer_algorithm);
    print_nonnull("customer_key_md5", customer_key_md5);
    print_nonnull("bucket_location", bucket_location);
    print_nonnull("obs_version", obs_version);
    print_nonnull("restore", restore);
    print_nonnull("obs_object_type", obs_object_type);
    print_nonnull("obs_next_append_position", obs_next_append_position);
    print_nonnull("obs_head_epid", obs_head_epid);
    print_nonnull("reserved_indicator", reserved_indicator);
    int i;
    for (i = 0; i < properties->meta_data_count; i++) {
        printf("x-obs-meta-%s: %s\n", properties->meta_data[i].name,
            properties->meta_data[i].value);
    }
    return OBS_STATUS_OK;
}
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data)
{
    if (callback_data) {
        obs_status *ret_status = (obs_status *)callback_data;
        *ret_status = status;
    }
    else {
        printf("Callback_data is NULL");
    }
    if (error && error->message) {
        printf("Error Message: \n   %s\n", error->message);
    }
    if (error && error->resource) {
        printf("Error Resource: \n  %s\n", error->resource);
    }
    if (error && error->further_details) {
        printf("Error further_details: \n   %s\n", error->further_details);
    }
    if (error && error->extra_details_count) {
        int i;
        for (i = 0; i < error->extra_details_count; i++) {
            printf("Error Extra Detail(%d):\n   %s:%s\n", i, error->extra_details[i].name,
                error->extra_details[i].value);
        }
    }
    if (error && error->error_headers_count) {
        int i;
        for (i = 0; i < error->error_headers_count; i++) {
            const char *errorHeader = error->error_headers[i];
            printf("Error Headers(%d):\n    %s\n", i, errorHeader == NULL ? "NULL Header" : errorHeader);
        }
    }
}
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData)
{
    tempAuthResult * ptrResult = (tempAuthResult *)callbackData;
    errno_t ret = strcpy_s(ptrResult->tmpAuthUrl, MAX_TEMP_URL_LEN, tempAuthUrl);
    if (ret != 0) { printf("ERROR: failed to copy temp auth URL.\n"); }
    ret = strcpy_s(ptrResult->actualHeaders, MAX_HEADER_LEN, tempAuthActualHeaders);
    if (ret != 0) { printf("ERROR: failed to copy temp auth headers.\n"); }
}

Code Examples: Generating a Temporary URL for Deleting an Object

This example generates a temporary URL for deleting an object.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include "eSDKOBS.h"
#include <stdio.h>
#define MAX_TEMP_URL_LEN 1024
#define MAX_HEADER_LEN 1024
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data);
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data); 
typedef struct __tempAuthResult
{
    char tmpAuthUrl[MAX_TEMP_URL_LEN];
    char actualHeaders[MAX_HEADER_LEN];
}tempAuthResult;
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData);
int main()
{
    // The following code shows how to generate a URL for deleting an object:
    // Call the obs_initialize method at the program entry to initialize global resources such as the network and memory.
    obs_status ret_status = obs_initialize(OBS_INIT_ALL);
    if (OBS_STATUS_OK != ret_status)
    {
        printf("obs_initialize failed(%s).\n", obs_get_status_name(ret_status));
        return -1;
    }
    obs_options options;
    // Create and initialize options, including the access domain name (host_name), access keys (access_key_id and access_key_secret), bucket name (bucket_name), and bucket storage class (storage_class).
    init_obs_options(&options);
    // Enter the endpoint corresponding to the bucket for host_name. CN-Hong Kong is used here as an example. Replace it with the one in your actual situation.
    options.bucket_options.host_name = "obs.ap-southeast-1.myhuaweicloud.com";
    // Hard-coded or plaintext AK and SK are risky. For security purposes, encrypt your AK and SK and store them in the configuration file or environment variables.
    // In this example, the AK and SK are stored in environment variables for identity authentication. Before running the code in this example, configure local environment variables ACCESS_KEY_ID and SECRET_ACCESS_KEY.
    options.bucket_options.access_key = getenv("ACCESS_KEY_ID");
    options.bucket_options.secret_access_key = getenv("SECRET_ACCESS_KEY");
    // Check whether environment variables are set.
    if (!options.bucket_options.access_key || !options.bucket_options.secret_access_key) {
        printf("ERROR: ACCESS_KEY_ID and SECRET_ACCESS_KEY environment variables must be set.\n");
        obs_deinitialize();
        return -1;
    }
    // Specify the bucket name, for example, example-bucket-name.
    char * bucket_name = "example-bucket-name";
    options.bucket_options.bucket_name = bucket_name;
    temp_auth_configure tempauth;
    tempAuthResult  ptrResult;
    memset(&ptrResult, 0, sizeof(tempAuthResult));
    //Callback data
    tempauth.callback_data = (void *)(&ptrResult);
    // Valid time (unit: second)
    tempauth.expires = 10;
    // The callback function returns the generated temporary URL.
    tempauth.temp_auth_callback = &tempAuthCallBack_getResult;
    options.temp_auth = &tempauth;
    // Assign values to the callback function.
    obs_response_handler response_handler =
    {
        &response_properties_callback,
        &response_complete_callback
    };
    ret_status = OBS_STATUS_BUTT;
    char* key = "example-object-key";
    char* versionid = NULL;
    // Information about the object to be deleted.
    obs_object_info object_info;
    memset(&object_info, 0, sizeof(obs_object_info));
    object_info.key = key;
    object_info.version_id = versionid;
    delete_object(&options, &object_info, &response_handler, &ret_status);
    // Check whether the request is successful.
    if (ret_status == OBS_STATUS_OK) {
        printf("the temporary signature url of put object generated successfully. \n"
            "the temporary signature url is %s. \n"
            "the actualHeaders are %s. \n", ptrResult.tmpAuthUrl, ptrResult.actualHeaders);
    }
    else
    {
        printf(" the temporary signature url of put object generation failed(%s).\n", obs_get_status_name(ret_status));
    }
    // Release the allocated global resources.
    obs_deinitialize();
}
// The response callback function. The content of properties in the callback can be recorded in callback_data (custom callback data).
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data)
{
    if (properties == NULL)
    {
        printf("error! obs_response_properties is null!");
        return OBS_STATUS_OK;      
    }
    // Print the response.
#define print_nonnull(name, field)                                 \
    do {                                                           \
        if (properties-> field) {                                  \
            printf("%s: %s\n", name, properties->field);          \
        }                                                          \
    } while (0)
    print_nonnull("request_id", request_id);
    print_nonnull("request_id2", request_id2);
    print_nonnull("content_type", content_type);
    if (properties->content_length) {
        printf("content_length: %llu\n", properties->content_length);
    }
    print_nonnull("server", server);
    print_nonnull("ETag", etag);
    print_nonnull("expiration", expiration);
    print_nonnull("website_redirect_location", website_redirect_location);
    print_nonnull("version_id", version_id);
    print_nonnull("allow_origin", allow_origin);
    print_nonnull("allow_headers", allow_headers);
    print_nonnull("max_age", max_age);
    print_nonnull("allow_methods", allow_methods);
    print_nonnull("expose_headers", expose_headers);
    print_nonnull("storage_class", storage_class);
    print_nonnull("server_side_encryption", server_side_encryption);
    print_nonnull("kms_key_id", kms_key_id);
    print_nonnull("customer_algorithm", customer_algorithm);
    print_nonnull("customer_key_md5", customer_key_md5);
    print_nonnull("bucket_location", bucket_location);
    print_nonnull("obs_version", obs_version);
    print_nonnull("restore", restore);
    print_nonnull("obs_object_type", obs_object_type);
    print_nonnull("obs_next_append_position", obs_next_append_position);
    print_nonnull("obs_head_epid", obs_head_epid);
    print_nonnull("reserved_indicator", reserved_indicator);
    int i;
    for (i = 0; i < properties->meta_data_count; i++) {
        printf("x-obs-meta-%s: %s\n", properties->meta_data[i].name,
            properties->meta_data[i].value);
    }
    return OBS_STATUS_OK;
}
// The completion callback function. The content of obs_status and obs_error_details in the callback can be recorded in callback_data (custom callback data).
void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data)
{
    if (callback_data) {
        obs_status *ret_status = (obs_status *)callback_data;
        *ret_status = status;
    }
    else {
        printf("Callback_data is NULL");
    }
    if (error && error->message) {
        printf("Error Message: \n   %s\n", error->message);
    }
    if (error && error->resource) {
        printf("Error Resource: \n  %s\n", error->resource);
    }
    if (error && error->further_details) {
        printf("Error further_details: \n   %s\n", error->further_details);
    }
    if (error && error->extra_details_count) {
        int i;
        for (i = 0; i < error->extra_details_count; i++) {
            printf("Error Extra Detail(%d):\n   %s:%s\n", i, error->extra_details[i].name,
                error->extra_details[i].value);
        }
    }
    if (error && error->error_headers_count) {
        int i;
        for (i = 0; i < error->error_headers_count; i++) {
            const char *errorHeader = error->error_headers[i];
            printf("Error Headers(%d):\n    %s\n", i, errorHeader == NULL ? "NULL Header" : errorHeader);
        }
    }
}
void tempAuthCallBack_getResult(char *tempAuthUrl, uint64_t tempAuthUrlLen, char *tempAuthActualHeaders,
    uint64_t tempAuthActualHeadersLen, void *callbackData)
{
    tempAuthResult * ptrResult = (tempAuthResult *)callbackData;
    errno_t ret = strcpy_s(ptrResult->tmpAuthUrl, MAX_TEMP_URL_LEN, tempAuthUrl);
    if (ret != 0) { printf("ERROR: failed to copy temp auth URL.\n"); }
    ret = strcpy_s(ptrResult->actualHeaders, MAX_HEADER_LEN, tempAuthActualHeaders);
    if (ret != 0) { printf("ERROR: failed to copy temp auth headers.\n"); }
}