使用oss c sdk自定义上传和下载callback

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 使用oss c sdk自定义上传和下载callback,简单预处理数据

       前段时间使用阿里云官网提供的OSS C SDK上传和下载数据,想在上传和下载过程中对数据进行一些简单的自定义预处理,看了一下oss c sdk的具体实现,大致了解如何通过自定义上传和下载的callback达到上述目的,这里做一个简单的分享。

       OSS C SDK在上传和下载数据时使用了CURL进行通信,之前简单学习过CURL的一些知识,知道CURL提供了一系列Callback,在上传下载时对数据进行一些处理,大家感兴趣的话可以参考: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html 。OSS C SDK针对OSS的常用场景,对用户暴露了两个最基本的Callback:CURLOPT_WRITEFUNCTION 和 CURLOPT_READFUNCTION。结合OSS C SDK使用这两个Callback实现上传数据和下载数据,可以大致了解整个过程。

1、上传数据

      OSS C SDK上传数据提供了两种方式:从memory读取、从文件读取。以从文件读取数据为例,我们看一下如何利用Callback实现从文件读取数据上传到OSS的。 
首先,我们熟悉oss c sdk中使用的一些数据结构: 
struct aos_http_request_s { 
    char *host; 
    uint8_t port; 
    char *signed_url; 
 
    http_method_e method; 
    char *uri; 
    char *resource; 
    aos_table_t *headers; 
    aos_table_t *query_params; 
 
    aos_list_t body; 
    int64_t body_len; 
    char *file_path; 
    aos_file_buf_t *file_buf; 
 
    aos_pool_t *pool; 
    void *user_data; 
    aos_read_http_body_pt read_body; 
 
    aos_http_body_type_e type; 
}; 
 
typedef enum { 
    BODY_IN_MEMORY = 0, 
    BODY_IN_FILE, 
    BODY_IN_CALLBACK 
aos_http_body_type_e; 
 
typedef int (*aos_read_http_body_pt)(aos_http_request_t *req, char *buffer, int len); 

OSS C SDK提供了oss_put_object_from_file接口用于从文件读取数据上传到OSS,重点看一下oss_write_request_body_from_file的实现: 
 
int oss_write_request_body_from_file(aos_pool_t *p, const aos_string_t *filename, aos_http_request_t *req) 
{ 
    int res = AOSE_OK; 
    aos_file_buf_t *fb = aos_create_file_buf(p); 
    res = aos_open_file_for_all_read(p, filename->data, fb); 
    if (res != AOSE_OK) { 
        aos_error_log("Open read file fail, filename:%s\n", filename->data); 
        return res; 
    } 
 
    req->body_len = fb->file_last; 
    req->file_path = filename->data; 
    req->file_buf = fb; 
    req->type = BODY_IN_FILE; 
    req->read_body = aos_read_http_body_file; 
 
    return res; 
} 
 

和上面的aos_http_request_s数据结构联系起来,可以看到在这里设置读取文件的相关信息的。接下来看一下这些设置如何和CURL提供的Callback联系上。

aos_http_transport_t *aos_curl_http_transport_create(aos_pool_t *p) 
{ 
    aos_func_u func; 
    aos_curl_http_transport_t *t; 
 
    t = (aos_curl_http_transport_t *)aos_pcalloc(p, sizeof(aos_curl_http_transport_t)); 
 
    t->pool = p; 
    t->options = aos_default_http_transport_options; 
    t->cleanup = aos_fstack_create(p, 5); 
 
    func.func1 = (aos_func1_pt)aos_transport_cleanup; 
    aos_fstack_push(t->cleanup, t, func, 1); 
 
    t->curl = aos_request_get(); 
    func.func1 = (aos_func1_pt)request_release; 
    aos_fstack_push(t->cleanup, t->curl, func, 1); 
 
    t->header_callback = aos_curl_default_header_callback; 
   t->read_callback = aos_curl_default_read_callback; 
    t->write_callback = aos_curl_default_write_callback; 
 
    return (aos_http_transport_t *)t; 
} 
 
size_t aos_curl_default_read_callback(char *buffer, size_t size, size_t nitems, void *instream) 
{ 
    int len; 
    int bytes; 
    aos_curl_http_transport_t *t; 
 
    t = (aos_curl_http_transport_t *)(instream); 
    len = size * nitems; 
 
    if (t->controller->error_code != AOSE_OK) { 
        aos_debug_log("abort read callback."); 
        return CURL_READFUNC_ABORT; 
    } 
 
    if ((bytes = t->req->read_body(t->req, buffer, len)) < 0) { 
        aos_debug_log("read body failure, %d.", bytes); 
        t->controller->error_code = AOSE_READ_BODY_ERROR; 
        t->controller->reason = "read body failure."; 
        return CURL_READFUNC_ABORT; 
    } 
 
    aos_move_transport_state(t, TRANS_STATE_BODY_OUT); 
 
    return bytes; 
} 
 
int aos_curl_transport_setup(aos_curl_http_transport_t *t) 
{ 
     ... 
     curl_easy_setopt_safe(CURLOPT_READFUNCTION, t->read_callback); 
     ... 
} 
 
红色部分基本已经说明了OSS C SDK如何调用CURL提供的CURLOPT_READFUNCTION了。参考OSS C SDK上传数据的实现大概也就知道如何对上传数据做一些简单的自定义了。

2、下载数据

下载数据常见的方式有两种:下载数据到memory、下载数据到文件。以下载数据到文件中为例,OSS C SDK使用CURL提供的Callback方式实现了数据下载 。首先,熟悉一下OSS C SDK中使用的一些数据结构:  
 
struct aos_http_response_s {  
    int status;  
    aos_table_t *headers;  
 
    aos_list_t body;  
    int64_t body_len;  
    char *file_path;  
    aos_file_buf_t* file_buf;  
    int64_t content_length;  
 
    aos_pool_t *pool;  
    void *user_data;  
    aos_write_http_body_pt write_body;  
    aos_http_body_type_e type;  
};  
 
typedef enum {         
    BODY_IN_MEMORY = 0,         
    BODY_IN_FILE,         
    BODY_IN_CALLBACK    
aos_http_body_type_e ;  
 
typedef int (*aos_write_http_body_pt)(aos_http_response_t *resp, const char *buffer, int len);  
 
       OSS C SDK提供了oss_get_object_to_file接口用于将OSS上的数据下载到本地文件中。重点看一下这个函数中 oss_init_read_response_body_to_file函数的实现:  
 
int  oss_init_read_response_body_to_file (aos_pool_t *p, const aos_string_t *filename, aos_http_response_t *resp)  
{  
    int res = AOSE_OK;  
    aos_file_buf_t *fb = aos_create_file_buf(p);  
    res =  aos_open_file_for_write(p, filename->data, fb);  
    if (res != AOSE_OK) {  
        aos_error_log("Open write file fail, filename:%s\n", filename->data);  
        return res;  
    }  
    resp->file_path = filename->data;  
    resp->file_buf = fb;  
    resp->write_body = aos_write_http_body_file;  
    resp->type = BODY_IN_FILE;  

    return res;  
}  
 
    这部分和上面的 aos_http_response_s数据结构联系起来,可以设置将下载数据写入本地文件。接下来看一下这些设置如何和CURL提供的Callback联系上。
aos_http_transport_t *aos_curl_http_transport_create(aos_pool_t *p)   {         
    aos_func_u func;         
    aos_curl_http_transport_t *t;    
     
    t = (aos_curl_http_transport_t *)aos_pcalloc(p, sizeof(aos_curl_http_transport_t));    
     
    t->pool = p;        
    t->options = aos_default_http_transport_options;         
    t->cleanup = aos_fstack_create(p, 5);    
    
    func.func1 = (aos_func1_pt)aos_transport_cleanup;         
    aos_fstack_push(t->cleanup, t, func, 1);    
      
    t->curl = aos_request_get();         
    func.func1 = (aos_func1_pt)request_release;         
    aos_fstack_push(t->cleanup, t->curl, func, 1);    
      
    t->header_callback = aos_curl_default_header_callback;       
    t->read_callback = aos_curl_default_read_callback;        
    t->write_callback = aos_curl_default_write_callback;        
 
 
    return (aos_http_transport_t *)t;    
}  
 
size_t  aos_curl_default_write_callback (char *ptr, size_t size, size_t nmemb, void *userdata) {  
    int len;    int bytes;  
    aos_curl_http_transport_t *t;  
 
    t = (aos_curl_http_transport_t *)(userdata);     
    len = size * nmemb;  
 
    if (t->controller->first_byte_time == 0) {  
        t->controller->first_byte_time = apr_time_now();    
    }  
 
    aos_curl_transport_headers_done(t);  
 
    if (t->controller->error_code != AOSE_OK) {  
        aos_debug_log("write callback abort");          
        return 0;  
    }  
 
    if (t->resp->status < 200 || t->resp->status > 299) {  
        bytes = aos_write_http_body_memory(t->resp, ptr, len);          
        assert(bytes == len);  
        aos_move_transport_state(t, TRANS_STATE_BODY_IN);         
        return bytes;  
    }  
 
    if (t->resp->type == BODY_IN_MEMORY && t->resp->body_len >= (int64_t)t->controller->options->max_memory_size) {          
         t->controller->reason = apr_psprintf(t->pool,   
              "receive body too big, current body size: %" APR_INT64_T_FMT ", max memory size: %" APR_INT64_T_FMT,    t->resp->body_len, t->controller->options->max_memory_size);  
        t->controller->error_code = AOSE_OVER_MEMORY;  
        aos_error_log("error reason:%s, ", t->controller->reason);  
        return 0;  
    }  
    if ((bytes = t->resp->write_body(t->resp, ptr, len)) < 0) {  
        aos_debug_log("write body failure, %d.", bytes);  
        t->controller->error_code = AOSE_WRITE_BODY_ERROR;  
        t->controller->reason = "write body failure.";  
        return 0;  
    }  
    aos_move_transport_state(t, TRANS_STATE_BODY_IN);  
    return bytes;  
}  
 
int aos_curl_transport_setup(aos_curl_http_transport_t *t) {  
     ...  
      curl_easy_setopt_safe(CURLOPT_WRITEFUNCTION, t->write_callback);  
    ...  
}  

红色部分基本说明了oss c sdk如何调用CURL提供的 CURLOPT_WRITEFUNCTION了。

       参考OSS C SDK使用CURL进行数据上传和下载的实现,能够根据自己的需求自定义数据上传和下载的Callback,对数据进行一些预处理。  
相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
目录
相关文章
|
30天前
|
存储 人工智能 开发工具
AI助理化繁为简,速取代码参数——使用python SDK 处理OSS存储的图片
只需要通过向AI助理提问的方式输入您的需求,即可瞬间获得核心流程代码及参数,缩短学习路径、提升开发效率。
1419 4
AI助理化繁为简,速取代码参数——使用python SDK 处理OSS存储的图片
|
3月前
|
运维 分布式计算 DataWorks
DataWorks产品使用合集之sdk的下载地址在哪里
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
3月前
|
API 开发工具 vr&ar
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
|
3月前
|
API 网络安全 开发工具
【Azure Developer - 密钥保管库 】使用 Python Azure SDK 实现从 Azure Key Vault Certificate 中下载证书(PEM文件)
【Azure Developer - 密钥保管库 】使用 Python Azure SDK 实现从 Azure Key Vault Certificate 中下载证书(PEM文件)
|
3月前
|
存储 Java 开发工具
【Azure Developer】VS Code运行Java 版Azure Storage SDK操作Blob (新建Container, 上传Blob文件,下载及清理)
【Azure Developer】VS Code运行Java 版Azure Storage SDK操作Blob (新建Container, 上传Blob文件,下载及清理)
|
4月前
|
存储 弹性计算 监控
建设云上稳定性问题之为什么要在云效平台创建发布流水线并将源代码编译环节替换为从OSS下载构建部署物
建设云上稳定性问题之为什么要在云效平台创建发布流水线并将源代码编译环节替换为从OSS下载构建部署物
|
4月前
|
消息中间件 分布式计算 DataWorks
DataWorks产品使用合集之如何使用Python和阿里云SDK读取OSS中的文件
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
3月前
|
开发工具 vr&ar 图形学
Pico Neo 3教程☀️ 一、SDK的下载与快速入门
Pico Neo 3教程☀️ 一、SDK的下载与快速入门
|
5月前
|
JSON 运维 Serverless
函数计算产品使用问题之如何实现数据的读取和修改,而不需要每次都从OSS下载完整的数据
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
JSON JavaScript 应用服务中间件
OSS callback功能常见问题分析
oss的callback功能常见错误有1、返回的body非json格式;2、status错误;3、超时
15229 0

热门文章

最新文章