使用自定义头域(Custom Headers)(C SDK)
开发过程中,您有任何问题可以在GitHub上提交issue,或者在华为云对象存储服务论坛中发帖求助。
功能说明
OBS C SDK 支持在发起请求时携带自定义 HTTP 头域。通过 obs_options.request_options 中的 custom_headers 字段设置,所有操作(PUT/GET/DELETE/LIST 等)均支持。
接口约束
| 头域前缀 | 大小写处理 | 是否参与签名 |
|---|---|---|
x-obs-* | 自动转小写 | 是 |
| 其他 | 保持原样 | 否 |
- 以 x-obs- 开头的头域名称会自动转为小写,并参与请求签名计算
- 其他头域保持原始大小写,仅作为 HTTP 头发送,不参与签名
- Content-Type、Content-MD5 等标准签名头应通过 obs_put_properties 设置,不要通过自定义头域传入
方法定义
| 参数名称 | 参数类型 | 是否必选 | 描述 |
|---|---|---|---|
| ustom_headers_count | int | 否 | 参数解释: 自定义头域的数量。 约束限制: 自定义头域与用户元数据(meta_data)共享内部数组。 取值范围: ≥ 0 的整数。为 0 时不发送自定义头域;为负数时等同于 0。 默认取值: 0 |
| custom_headers | 否 | 参数解释: 自定义头域数组,每个元素为一个表2 obs_name_value 键值对。 约束限制: 当 custom_headers_count > 0 时不能为 NULL;每个元素的 name 和 value 不能为 NULL,否则该条目被跳过。所有头域的原始字节总长度不超过 OBS_MAX_METADATA_SIZE(4096 字节),超出返回 OBS_STATUS_MetadataHeadersTooLong。不要通过此字段设置 Content-Type、Content-MD5 等标准签名头,应通过 obs_put_properties 对应字段设置,否则可能导致签名不一致。 取值范围: 指向 obs_name_value 数组的指针,数组长度须 ≥ custom_headers_count。 默认取值: NULL |
代码示例一:上传对象时携带自定义头域
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 | #include "eSDKOBS.h" #include <stdlib.h> // 响应回调 void response_complete_callback(obs_status status, const obs_error_details *error, void *callback_data) { if (status != OBS_STATUS_OK) { printf("request failed, status=%d\n", status); if (error && error->message) { printf("error: %s\n", error->message); } } else { printf("request succeeded\n"); } } obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data) { return OBS_STATUS_OK; } int main() { // 1. 初始化 options obs_options options; init_obs_options(&options); // host_name填写桶所在的endpoint, 此处以华北-北京四为例,其他地区请按实际情况填写。 options.bucket_options.host_name = "obs.cn-north-4.myhuaweicloud.com"; options.bucket_options.bucket_name = "your-bucket"; // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; // 本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY。 options.bucket_options.access_key = getenv("ACCESS_KEY_ID"); options.bucket_options.secret_access_key = getenv("SECRET_ACCESS_KEY"); // 2. 设置自定义头域 obs_name_value headers[2]; headers[0].name = "x-obs-request-source"; headers[0].value = "sdk-custom-header"; headers[1].name = "X-Client-Version"; headers[1].value = "1.0.0"; options.request_options.custom_headers = headers; options.request_options.custom_headers_count = 2; // 3. 设置上传属性 obs_put_properties put_properties; init_put_properties(&put_properties); put_properties.content_type = "text/plain"; // 4. 构造回调 obs_put_object_handler handler = {{&response_properties_callback, &response_complete_callback}, NULL}; // 5. 上传对象(自定义头域会自动携带) char *key = "test-object.txt"; char *data = "Hello OBS!"; put_object(&options, key, strlen(data), &put_properties, NULL, &handler, NULL); return 0; } |
该请求发出的 HTTP 头将包含:
x-obs-request-source: sdk-custom-header <- 参与签名(名称已转小写) X-Client-Version: 1.0.0 <- 不参与签名(保持原始大小写)
代码示例二:下载对象时携带自定义头域
obs_options options;
init_obs_options(&options);
// ... 设置 bucket_options ...
// 设置自定义头域
obs_name_value headers[1];
headers[0].name = "x-obs-request-source";
headers[0].value = "download-with-custom-header";
options.request_options.custom_headers = headers;
options.request_options.custom_headers_count = 1;
// 下载对象
obs_object_info object_info;
object_info.key = "test-object.txt";
object_info.version_id = NULL;
obs_response_handler handler =
{&response_properties_callback, &response_complete_callback};
get_object(&options, &object_info, NULL, &handler, NULL)