ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

libcurl 获取上传预期大小:CURLINFO_CONTENT_LENGTH_UPLOAD_T 接口详解与源码实现剖析

libcurl 获取上传预期大小:CURLINFO_CONTENT_LENGTH_UPLOAD_T 接口详解与源码实现剖析 libcurl 获取上传预期大小CURLINFO_CONTENT_LENGTH_UPLOAD_T 接口详解与源码实现剖析【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curlCURLINFO_CONTENT_LENGTH_UPLOAD_T 是 libcurl 中用于查询「本次上传任务预期间大小」的 curl_off_t 型信息项适用于全部支持上传的协议All。本文围绕 docs/libcurl/opts/CURLINFO_CONTENT_LENGTH_UPLOAD_T.md 展开结合 lib/getinfo.c、lib/progress.c 等源码讲清该选项的语义、与 CURLINFO_SIZE_UPLOAD_T 的差异、底层数据流并给出可直接编译运行的 C 语言示例帮助你准确地在自己的上传流程里读取「声明的上传大小」。接口速览该选项通过curl_easy_getinfo读取声明如下完整签名见原文档 SYNOPSIS#include curl/curl.h CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_CONTENT_LENGTH_UPLOAD_T, curl_off_t *content_length);项目说明返回类型curl_off_t64 位有符号整数适用协议All所有支持上传的协议加入版本Added in 7.55.0传入方式指向curl_off_t变量的指针语义读取的是「预期上传量」而非「实际上传量」文档对该选项的定位非常明确它是客户端在传输开始之前声明specified的期望上传大小即 transfer start 之前设置好的预期数据量。与之形成对照的是CURLINFO_SIZE_UPLOAD_T—— 它返回的是传输结束时实际上传了多少字节。在许多场景下两者数值相同但语义完全不同CURLINFO_CONTENT_LENGTH_UPLOAD_T预期值来自传输前的声明CURLINFO_SIZE_UPLOAD_T实际值来自传输过程的统计计数。当大小未知时CURLINFO_CONTENT_LENGTH_UPLOAD_T返回-1这在 7.55.0 引入时即已确定参见 CURLINFO_CONTENT_LENGTH_UPLOAD.md 中“Since 7.19.4, this returns -1 if the size is not known”的旧接口对应描述。从源码看这一行为由 lib/getinfo.c 的getinfo_offt分支实现case CURLINFO_CONTENT_LENGTH_UPLOAD_T: *param_offt >/* the sizes are unknown at start */ p-dl_size_known FALSE; p-ul_size_known FALSE;2. 由各协议层在传输前设置Curl_pgrsSetUploadSize()是写入预期大小的统一入口定义于 lib/progress.cvoid Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size) { if(size 0) { >CURLINFO_CONTENT_LENGTH_UPLOAD CURL_DEPRECATED(7.55.0, Use CURLINFO_CONTENT_LENGTH_UPLOAD_T) CURLINFO_DOUBLE 16, CURLINFO_CONTENT_LENGTH_UPLOAD_T CURLINFO_OFF_T 16,旧接口CURLINFO_CONTENT_LENGTH_UPLOAD返回double自7.55.0起被标记为废弃deprecated完整描述与示例见 CURLINFO_CONTENT_LENGTH_UPLOAD.md新接口CURLINFO_CONTENT_LENGTH_UPLOAD_T返回curl_off_t更适合表达大文件字节数double在超大数值上存在精度损失风险并且该枚举位于CURLINFO_OFF_T类型组16由getinfo_offt分发处理见 lib/getinfo.c 的 switch 分支。4. 与下载侧、实际上传量的完整对比信息项类型语义源码位置lib/getinfo.cCURLINFO_CONTENT_LENGTH_UPLOAD_Tcurl_off_t预期上传大小未知为 -1L428-L431CURLINFO_CONTENT_LENGTH_DOWNLOAD_Tcurl_off_t预期下载大小未知为 -1L424-L427CURLINFO_SIZE_UPLOAD_Tcurl_off_t实际上传字节数L412-L414CURLINFO_SIZE_DOWNLOAD_Tcurl_off_t实际下载字节数L415-L417下载侧的预期大小同样来自dl_size_known/dl.total_size参考 CURLINFO_CONTENT_LENGTH_DOWNLOAD_T.md。完整可运行示例下面示例在原文档 EXAMPLE 基础上补全先构造一个带CURLOPT_UPLOAD的上传请求用CURLOPT_INFILESIZE_LARGE声明文件大小传输完成后同时打印“预期上传大小”与“实际上传大小”直观对比两个信息项#include stdio.h #include string.h #include curl/curl.h /* 模拟从本地读取上传数据的回调 */ static size_t read_cb(char *ptr, size_t size, size_t nmemb, void *userdata) { const char *payload hello libcurl upload; size_t len strlen(payload); if((size * nmemb) len) return 0; memcpy(ptr, payload, len); return len; } int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; curl_off_t expected -1; /* 预期上传大小 */ curl_off_t actual -1; /* 实际上传大小 */ curl_easy_setopt(curl, CURLOPT_URL, https://example.com/upload); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_cb); /* 显式声明上传体长度使“预期大小”可知 */ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)strlen(hello libcurl upload)); result curl_easy_perform(curl); if(result CURLE_OK) { /* 读取预期上传大小 */ result curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_UPLOAD_T, expected); if(result CURLE_OK) { printf(Specified upload size: % CURL_FORMAT_CURL_OFF_T \n, expected); } /* 读取实际上传大小 */ result curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, actual); if(result CURLE_OK) { printf(Actually uploaded size: % CURL_FORMAT_CURL_OFF_T \n, actual); } } curl_easy_cleanup(curl); } return 0; }关键点说明CURLOPT_INFILESIZE_LARGE显式声明上传长度若省略且无法从数据源获知长度则expected会得到 -1打印curl_off_t必须使用CURL_FORMAT_CURL_OFF_T格式化宏示例中printf的正确写法CURLINFO_SIZE_UPLOAD_T与预期值常相同但若服务器中途断开、上传被截断二者就会出现差异这也是用CONTENT_LENGTH_UPLOAD_T做“声明值”核对的价值所在。返回值与错误处理curl_easy_getinfo的返回值遵循统一的 CURLcode 约定详见 libcurl-errors 文档CURLE_OK (0)调用成功content_length被写入有效值可能为 -1表示未知这不是错误非零发生错误。若传入的信息项不被当前 libcurl 构建支持则可能返回CURLE_UNKNOWN_OPTION参见 lib/getinfo.c 的 default 分支。因此判断“预期大小是否已知”的正确方式是检查读出的content_length是否为 -1而不是把 -1 当作调用失败。使用提示小结读取时机该值在传输开始前即已确定curl_easy_perform返回后读取即可无需在回调中轮询-1 的含义不代表错误仅代表传输发起时大小未知如流式上传、chunked 编码且未声明长度优先使用_T后缀版本CURLINFO_CONTENT_LENGTH_UPLOADdouble 版自 7.55.0 起废弃新代码应统一使用本文的CURLINFO_CONTENT_LENGTH_UPLOAD_T与进度类选项配合该值基于data-progress统计结构与进度回调、CURLINFO_SIZE_UPLOAD_T等共用同一套计数器可在同一处获取协议无关只要是 libcurl 支持的上传协议HTTP、FTP、SFTP、SMTP、IMAP、TFTP、SMB 等该接口行为一致具体写入路径可参考上文列出的各协议模块对Curl_pgrsSetUploadSize的调用。【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表