All Products
Search
Document Center

Object Storage Service:Cross-origin resource sharing (C SDK)

Last Updated:Mar 20, 2026

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 rules

    • oss:GetBucketCors — to retrieve CORS rules

    • oss:DeleteBucketCors — to delete CORS rules

  • The OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment 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.

FieldTypeRequiredDescription
allowed_origin_liststring listYesOrigins allowed to make cross-origin requests. Use * to allow any origin.
allowed_method_liststring listYesHTTP methods allowed for cross-origin requests. Valid values: GET, PUT, POST, DELETE, HEAD.
allowed_head_liststring listNoRequest headers that the browser may include in a cross-origin request (maps to Access-Control-Request-Headers).
expose_head_liststring listNoResponse headers that the browser is allowed to access (maps to Access-Control-Expose-Headers).
max_age_secondsintegerNoHow 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;
}

References