Cross-Origin Resource Sharing (CORS) controls which origins, HTTP methods, and headers can make cross-origin requests to your OSS bucket. If you serve assets from one domain and access them from another—such as a browser-based web app calling OSS directly—configure CORS rules on the bucket to allow those requests. Use the C SDK to set, retrieve, and delete CORS rules programmatically.
Prerequisites
Before you begin, make sure that you have:
OSS C SDK 3.6.0 or later
The required RAM permissions:
oss:PutBucketCors— to configure CORS rulesoss:GetBucketCors— to retrieve CORS rulesoss:DeleteBucketCors— to delete CORS rules
The
OSS_ACCESS_KEY_IDandOSS_ACCESS_KEY_SECRETenvironment variables set with your AccessKey credentials
For permission setup, see Attach a custom policy to a RAM user.
These examples use the public endpoint for the China (Hangzhou) region. If you access OSS from another Alibaba Cloud service in the same region, use the internal endpoint instead. For endpoint details, see Regions and endpoints. To create an OSSClient instance with a custom domain name or Security Token Service (STS), see Initialization.
CORS rule fields
Each CORS rule is an oss_cors_rule_t struct. The following table describes the available fields.
| Field | Type | Required | Description |
|---|---|---|---|
allowed_origin_list | string list | Yes | Origins allowed to make cross-origin requests. Use * to allow any origin. |
allowed_method_list | string list | Yes | HTTP methods allowed for cross-origin requests. Valid values: GET, PUT, POST, DELETE, HEAD. |
allowed_head_list | string list | No | Request headers that the browser may include in a cross-origin request (maps to Access-Control-Request-Headers). |
expose_head_list | string list | No | Response headers that the browser is allowed to access (maps to Access-Control-Expose-Headers). |
max_age_seconds | integer | No | How long (in seconds) browsers may cache the preflight response. |
Set CORS rules
The following example configures two CORS rules on a bucket: one that allows write requests from a specific origin, and one that allows read requests from any origin.
#include "oss_api.h"
#include "aos_http_io.h"
/* Set yourEndpoint to the endpoint of the region where the bucket is located.
For example, if the bucket is in the China (Hangzhou) region, set the endpoint
to https://oss-cn-hangzhou.aliyuncs.com. */
const char *endpoint = "yourEndpoint";
/* Specify the bucket name. Example: examplebucket. */
const char *bucket_name = "examplebucket";
/* Set yourRegion to the region where the bucket is located.
For example, if the bucket is in the China (Hangzhou) region, set the region to cn-hangzhou. */
const char *region = "yourRegion";
void init_options(oss_request_options_t *options)
{
options->config = oss_config_create(options->pool);
/* Initialize an aos_string_t type with a char* string. */
aos_str_set(&options->config->endpoint, endpoint);
/* Obtain access credentials from environment variables. Before running this sample code,
make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. */
aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
/* Configure the region and signature version. */
aos_str_set(&options->config->region, region);
options->config->signature_version = 4;
/* Specifies whether a CNAME is used. 0 indicates that a CNAME is not used. */
options->config->is_cname = 0;
/* Set network parameters, such as the timeout period. */
options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
/* At the program entry, call the aos_http_io_initialize method to initialize
global resources, such as the network and memory. */
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
exit(1);
}
/* The memory pool (pool) for memory management is equivalent to apr_pool_t.
Its implementation code is in the apr library. */
aos_pool_t *pool;
/* Create a memory pool. The second parameter is NULL, which indicates that
the new memory pool does not inherit from another memory pool. */
aos_pool_create(&pool, NULL);
/* Create and initialize options. This parameter includes global configuration
information, such as endpoint, access_key_id, access_key_secret, is_cname, and curl. */
oss_request_options_t *oss_client_options;
/* Allocate memory for options in the memory pool. */
oss_client_options = oss_request_options_create(pool);
/* Initialize the client options oss_client_options. */
init_options(oss_client_options);
/* Initialize parameters. */
aos_string_t bucket;
aos_table_t *resp_headers = NULL;
aos_status_t *resp_status = NULL;
aos_list_t cors_rule_list;
oss_cors_rule_t *cors_rule1 = NULL, *cors_rule2 = NULL;
aos_str_set(&bucket, bucket_name);
aos_list_init(&cors_rule_list);
/* Rule 1: allow PUT and GET requests from https://www.example.com,
with the Authorization header and x-oss-request-id exposed in the response. */
cors_rule1 = oss_create_cors_rule(pool);
aos_list_add_tail(&cors_rule1->node, &cors_rule_list);
oss_create_sub_cors_rule(pool, &cors_rule1->allowed_origin_list, "https://www.example.com");
oss_create_sub_cors_rule(pool, &cors_rule1->allowed_method_list, "PUT");
oss_create_sub_cors_rule(pool, &cors_rule1->allowed_method_list, "GET");
oss_create_sub_cors_rule(pool, &cors_rule1->allowed_head_list, "Authorization");
oss_create_sub_cors_rule(pool, &cors_rule1->expose_head_list, "x-oss-request-id");
/* Rule 2: allow GET requests from any origin. */
cors_rule2 = oss_create_cors_rule(pool);
aos_list_add_tail(&cors_rule2->node, &cors_rule_list);
oss_create_sub_cors_rule(pool, &cors_rule2->allowed_origin_list, "*");
oss_create_sub_cors_rule(pool, &cors_rule2->allowed_method_list, "GET");
oss_create_sub_cors_rule(pool, &cors_rule2->allowed_head_list, "Authorization");
/* Set CORS rules. */
resp_status = oss_put_bucket_cors(oss_client_options, &bucket, &cors_rule_list, &resp_headers);
if (aos_status_is_ok(resp_status)) {
printf("put bucket cors succeeded\n");
} else {
printf("put bucket cors failed\n");
}
/* Release the memory pool. This releases the memory allocated to resources during the request. */
aos_pool_destroy(pool);
/* Release the previously allocated global resources. */
aos_http_io_deinitialize();
return 0;
}Get CORS rules
The following example retrieves and prints all CORS rules configured on the bucket.
#include "oss_api.h"
#include "aos_http_io.h"
const char *endpoint = "yourEndpoint";
const char *bucket_name = "examplebucket";
const char *region = "yourRegion";
void init_options(oss_request_options_t *options)
{
options->config = oss_config_create(options->pool);
aos_str_set(&options->config->endpoint, endpoint);
aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
aos_str_set(&options->config->region, region);
options->config->signature_version = 4;
options->config->is_cname = 0;
options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
exit(1);
}
aos_pool_t *pool;
aos_pool_create(&pool, NULL);
oss_request_options_t *oss_client_options;
oss_client_options = oss_request_options_create(pool);
init_options(oss_client_options);
aos_string_t bucket;
aos_table_t *resp_headers = NULL;
aos_status_t *resp_status = NULL;
aos_list_t cors_rule_list;
oss_cors_rule_t *cors_rule = NULL;
oss_sub_cors_rule_t *sub_cors_rule = NULL;
aos_str_set(&bucket, bucket_name);
aos_list_init(&cors_rule_list);
/* Get CORS rules. */
resp_status = oss_get_bucket_cors(oss_client_options, &bucket, &cors_rule_list, &resp_headers);
if (aos_status_is_ok(resp_status)) {
printf("get bucket cors succeeded\n");
aos_list_for_each_entry(oss_cors_rule_t, cors_rule, &cors_rule_list, node) {
printf("max_age_seconds: %d\n", cors_rule->max_age_seconds);
aos_list_for_each_entry(oss_sub_cors_rule_t, sub_cors_rule, &cors_rule->allowed_origin_list, node) {
printf("allowed_origin_list: %s \n", sub_cors_rule->rule.data);
}
aos_list_for_each_entry(oss_sub_cors_rule_t, sub_cors_rule, &cors_rule->allowed_method_list, node) {
printf("allowed_method_list: %s \n", sub_cors_rule->rule.data);
}
aos_list_for_each_entry(oss_sub_cors_rule_t, sub_cors_rule, &cors_rule->allowed_head_list, node) {
printf("allowed_head_list: %s \n", sub_cors_rule->rule.data);
}
aos_list_for_each_entry(oss_sub_cors_rule_t, sub_cors_rule, &cors_rule->expose_head_list, node) {
printf("expose_head_list: %s \n", sub_cors_rule->rule.data);
}
}
} else {
printf("get bucket cors failed\n");
}
aos_pool_destroy(pool);
aos_http_io_deinitialize();
return 0;
}Delete CORS rules
The following example deletes all CORS rules configured on the bucket.
#include "oss_api.h"
#include "aos_http_io.h"
const char *endpoint = "yourEndpoint";
const char *bucket_name = "examplebucket";
const char *region = "yourRegion";
void init_options(oss_request_options_t *options)
{
options->config = oss_config_create(options->pool);
aos_str_set(&options->config->endpoint, endpoint);
aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
aos_str_set(&options->config->region, region);
options->config->signature_version = 4;
options->config->is_cname = 0;
options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
exit(1);
}
aos_pool_t *pool;
aos_pool_create(&pool, NULL);
oss_request_options_t *oss_client_options;
oss_client_options = oss_request_options_create(pool);
init_options(oss_client_options);
aos_string_t bucket;
aos_table_t *resp_headers = NULL;
aos_status_t *resp_status = NULL;
aos_str_set(&bucket, bucket_name);
/* Delete CORS rules. */
resp_status = oss_delete_bucket_cors(oss_client_options, &bucket, &resp_headers);
if (aos_status_is_ok(resp_status)) {
printf("delete bucket cors succeeded\n");
} else {
printf("delete bucket cors failed\n");
}
aos_pool_destroy(pool);
aos_http_io_deinitialize();
return 0;
}