开发者社区> 问答> 正文

是官方C SDK的bug还是OSS服务器的bug????

目标任务:创建出对象obj_name的符号链接obj_link
开发环境:使用官方的OSS C SDK
结果:没有正确创建出符号链接obj_link,创建出的对象名为obj_link%3Fsymlink,且不具备符号链接属性
进一步测试:不做url编码,oss服务器能够正确创建符号链接
直接原因:c sdk在发请求到网络之前对名字做了url编码,obj_link?symlink被编码为了obj_link%3Fsymlink,但是服务器不能正确处理url编码后的请求
进一步分析:
1.Authorization: SignatureValue在sdk中的计算先于url编码,而服务器收到请求后并不会拒绝请求,说明请求接收的模块能够正确处理url编码,在url decode之后再做的Authorization校验;
2.创建出的符号链接名字错误,说明oss模块不具备处理url编码的功能,或者说是负责向oss转发指令的模块不具备识别url编码的能力
3.如果不承认服务器有问题,也可以说是sdk在处理的时候无差别对待object_name不恰当

使用oss c sdk实现创建符号链接关键代码:
const char BUCKET_NAME[] = "xxxxxx";
const char OSS_SYMLINK_TAEGET[] = "x-oss-symlink-target";

aos_status_t *oss_put_symlink(const oss_request_options_t *options,
    const aos_string_t *bucket,
    const aos_string_t *symlink_object,
    const aos_string_t *target_object,
    aos_table_t *headers,
    aos_table_t **resp_headers)
{
    aos_status_t *s = NULL;
    aos_http_request_t *req = NULL;
    aos_http_response_t *resp = NULL;
    aos_table_t *query_params = NULL;
    char* tagname = NULL;

    headers = aos_table_create_if_null(options, headers, 0);

    query_params = aos_table_create_if_null(options, query_params, 0);

    tagname = aos_pstrdup(options->pool, target_object);
    apr_table_add(headers, OSS_SYMLINK_TAEGET, tagname);

    oss_init_object_request(options, bucket, symlink_object, HTTP_PUT,
        &req, query_params, headers, NULL, 0, &resp);

    s = oss_process_request(options, req, resp);
    oss_fill_read_response_header(resp, resp_headers);

    return s;
}

void put_object_symlink()
{
    aos_pool_t *p = NULL;
    aos_string_t bucket;
    aos_string_t symlink_object;
    aos_string_t target_object;
    int is_cname = 0;
    aos_table_t *headers = NULL;
    aos_table_t *resp_headers = NULL;
    oss_request_options_t *options = NULL;
    aos_list_t buffer;
    aos_buf_t *content = NULL;
    char *str = "";
    aos_status_t *s = NULL;

    char* pbuf = NULL;

    aos_pool_create(&p, NULL);
    options = oss_request_options_create(p);
    init_sample_request_options(options, is_cname);
    headers = aos_table_make(p, 1);
    apr_table_set(headers, "x-oss-meta-author", "oss");
    aos_str_set(&bucket, BUCKET_NAME);
    aos_str_set(&symlink_object, "obj_link?symlink");// 符号链接名
    aos_str_set(&target_object, "obj_name"); // 目标对象名

    aos_list_init(&buffer);
    content = aos_buf_pack(options->pool, str, strlen(str));
    aos_list_add_tail(&content->node, &buffer);

    s = oss_put_symlink(options, &bucket, &symlink_object, &target_object, headers, &resp_headers);

    if (aos_status_is_ok(s)) {
        printf("put object symlink succeeded\n");
    }
    else {
        printf("put object symlink failed\n");
    }

    aos_pool_destroy(p);
}


展开
收起
伏神 2017-03-17 13:33:26 3456 0
2 条回答
写回答
取消 提交回答
  • Re是官方C SDK的bug还是OSS服务器的bug????
    C SDK没有问题,是我自己没有用对,我仔细看了sdk的源码实现,是我不该直接把?symlink放到对象名字后面作为文件名传入,应该把symlink作为请求参数传入,这样就不会对?编码了;
    我把封装好的创建符号链接代码和使用示例代码传上来供需要的同学参考。
    const char BUCKET_NAME[] = "xxxxxx";
    const char OSS_SYMLINK_TAEGET[] = "x-oss-symlink-target";
    const char OSS_REQ_PARAM_SYMLINK[] = "symlink";

    aos_status_t *oss_put_symlink(const oss_request_options_t *options,
            const aos_string_t *bucket,
            const aos_string_t *symlink_object,
            const aos_string_t *target_object,
            aos_table_t *headers,
            aos_table_t **resp_headers)
    {
            aos_status_t *s = NULL;
            aos_http_request_t *req = NULL;
            aos_http_response_t *resp = NULL;
            aos_table_t *query_params = NULL;
            char* targname = NULL;

            headers = aos_table_create_if_null(options, headers, 0);
            query_params = aos_table_create_if_null(options, query_params, 0);

            apr_table_add(query_params, OSS_REQ_PARAM_SYMLINK, ""); // symlink request key without value

            targname = aos_pstrdup(options->pool, target_object);
            apr_table_add(headers, OSS_SYMLINK_TAEGET, targname);

            oss_init_object_request(options, bucket, symlink_object, HTTP_PUT,
                    &req, query_params, headers, NULL, 0, &resp);

            s = oss_process_request(options, req, resp);
            oss_fill_read_response_header(resp, resp_headers);

            return s;
    }

    aos_status_t *oss_get_symlink(const oss_request_options_t *options,
            const aos_string_t *bucket,
            const aos_string_t *symlink_object,
            aos_table_t *headers,
            aos_table_t **resp_headers)
    {
            aos_status_t *s = NULL;
            aos_http_request_t *req = NULL;
            aos_http_response_t *resp = NULL;
            aos_table_t *query_params = NULL;

            headers = aos_table_create_if_null(options, headers, 0);
            query_params = aos_table_create_if_null(options, query_params, 0);

            apr_table_add(query_params, OSS_REQ_PARAM_SYMLINK, ""); // symlink request key without value

            oss_init_object_request(options, bucket, symlink_object, HTTP_GET,
                    &req, query_params, headers, NULL, 0, &resp);

            s = oss_process_request(options, req, resp);
            oss_fill_read_response_header(resp, resp_headers);

            return s;
    }



    ///////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////
    void put_object_symlink()
    {
            aos_pool_t *p = NULL;
            aos_string_t bucket;
            aos_string_t symlink_object;
            aos_string_t target_object;
            int is_cname = 0;
            aos_table_t *headers = NULL;
            aos_table_t *resp_headers = NULL;
            oss_request_options_t *options = NULL;
            aos_list_t buffer;
            aos_buf_t *content = NULL;
            char *str = "";
            aos_status_t *s = NULL;
            char* pbuf = NULL;
            aos_pool_create(&p, NULL);
            options = oss_request_options_create(p);
            init_sample_request_options(options, is_cname);
            headers = aos_table_make(p, 1);
            apr_table_set(headers, "x-oss-meta-author", "oss");
            aos_str_set(&bucket, BUCKET_NAME);
            aos_str_set(&symlink_object, "obj_link");// 符号链接名
            aos_str_set(&target_object, "obj_name"); // 目标对象名
            aos_list_init(&buffer);
            content = aos_buf_pack(options->pool, str, strlen(str));
            aos_list_add_tail(&content->node, &buffer);
            s = oss_put_symlink(options, &bucket, &symlink_object, &target_object, headers, &resp_headers);
            if (aos_status_is_ok(s)) {
                    printf("put object symlink succeeded\n");
            }
            else {
                    printf("put object symlink failed\n");
            }
            aos_pool_destroy(p);
    }

    void get_object_symlink()
    {
            aos_pool_t *p = NULL;
            aos_string_t bucket;
            aos_string_t symlink_object;
            int is_cname = 0;
            aos_table_t *headers = NULL;
            aos_table_t *resp_headers = NULL;
            oss_request_options_t *options = NULL;
            aos_list_t buffer;
            aos_buf_t *content = NULL;
            char *str = "";
            aos_status_t *s = NULL;

            char* pLink = NULL;

            aos_pool_create(&p, NULL);
            options = oss_request_options_create(p);
            init_sample_request_options(options, is_cname);
            headers = aos_table_make(p, 1);
            apr_table_set(headers, "x-oss-meta-author", "oss");
            aos_str_set(&bucket, BUCKET_NAME);
            aos_str_set(&symlink_object, "obj_link");

            aos_list_init(&buffer);
            content = aos_buf_pack(options->pool, str, strlen(str));
            aos_list_add_tail(&content->node, &buffer);

            s = oss_get_symlink(options, &bucket, &symlink_object, headers, &resp_headers);

            if (aos_status_is_ok(s))
            {
                    printf("get object symlink succeeded\n");
                    pLink = apr_table_get(resp_headers, "x-oss-symlink-target");
            }
            else
            {
                    printf("get object symlink failed\n");
            }

            aos_pool_destroy(p);
    }


    2017-03-21 12:53:52
    赞同 展开评论 打赏
  • 嗯,看来只能试着绕过c sdk自己做个接口了

    -------------------------

    您的无私奉献精神值得我们学习!向您致敬!

    2017-03-18 12:01:44
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
一个跨平台的云服务SDK需要什么 立即下载
云存储之OSS实战进阶分享 立即下载
OSS运维进阶实战手册 立即下载