libcurl 条件请求判定:CURLINFO_CONDITION_UNMET 使用指南
libcurl 条件请求判定CURLINFO_CONDITION_UNMET 使用指南【免费下载链接】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本篇技术指南围绕 libcurl 提供的CURLINFO_CONDITION_UNMET信息选项展开讲解如何通过curl_easy_getinfo判断一次基于时间条件的 HTTP/FTP/FILE 传输是否因条件未满足而被跳过例如服务器返回 304 或资源未按预期更新并结合当前仓库源码剖析其底层实现与判定逻辑。读完本文你将掌握条件请求的完整搭配方案、返回值语义与实战代码写法。什么是 CURLINFO_CONDITION_UNMETCURLINFO_CONDITION_UNMET是 libcurl 的一个信息info选项用于在传输结束后查询上一次请求设置的时间条件time condition是否未被满足。它属于long类型的 getinfo 选项枚举值为CURLINFO_LONG 35定义见 include/curl/curl.h自 curl 7.19.4 版本起加入仅适用于 HTTP 协议。典型场景当客户端发送带If-Modified-Since之类的条件请求服务器判定资源未更新于是不返回文档正文。此时curl_easy_perform仍然返回CURLE_OK毕竟请求本身成功了但下载到的数据量为零。如果不对返回内容加以区分很容易把资源未更新误当成下载失败或空文件。CURLINFO_CONDITION_UNMET正是用来消解这种歧义的它告诉你这次成功的空传输到底是条件未满足还是本来就该这样。接口原型#include curl/curl.h CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_CONDITION_UNMET, long *unmet);传入一个指向long的指针curl_easy_getinfo会把结果写入该变量返回1之前请求中设置的条件未匹配。即你没有拿到数据是因为资源不满足你提出的时间条件返回0条件已满足或从未设置条件传输正常进行。此外即使你没有显式设置时间条件只要服务器以HTTP 304状态码响应例如客户端主动发送了自定义的If-Match-*请求头该选项同样会返回 1。底层实现flag 如何被置位getinfo 的读取逻辑curl_easy_getinfo对CURLINFO_CONDITION_UNMET的处理位于 lib/getinfo.ccase CURLINFO_CONDITION_UNMET: if(data-info.httpcode 304) *param_longp 1L; else /* return if the condition prevented the document to get transferred */ *param_longp >bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) { if((timeofdoc 0) || (data-set.timevalue 0)) return TRUE; switch(data-set.timecondition) { case CURL_TIMECOND_IFMODSINCE: default: if(timeofdoc >int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; curl_easy_setopt(curl, CURLOPT_URL, https://example.com); /* January 1, 2020 is 1577833200 */ curl_easy_setopt(curl, CURLOPT_TIMEVALUE, 1577833200L); /* If-Modified-Since the above time stamp */ curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); /* Perform the request */ result curl_easy_perform(curl); if(result CURLE_OK) { /* check the time condition */ long unmet; result curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, unmet); if(result CURLE_OK) { printf(The time condition was %sfulfilled\n, unmet ? NOT : ); } } curl_easy_cleanup(curl); } return 0; }代码要点CURLOPT_TIMEVALUE设置对比用的时间戳Unix 秒数示例中1577833200即 2020-01-01 00:00:00 UTCCURLOPT_TIMECONDITION设置为CURL_TIMECOND_IFMODSINCE表示只在资源修改时间晚于该时间戳时才传输curl_easy_perform返回CURLE_OK后用CURLINFO_CONDITION_UNMET查询条件是否未满足unmet为 1 时打印NOT fulfilled说明传输被条件跳过为 0 时打印fulfilled说明资源满足条件、数据已正常接收。配套选项与时间条件语义CURLINFO_CONDITION_UNMET本身只负责查询结果条件请求的建立依赖两个 setopt 选项详见 docs/libcurl/opts/CURLOPT_TIMECONDITION.md选项作用取值CURLOPT_TIMEVALUE指定对比用时间戳Unix 时间秒long 类型CURLOPT_TIMECONDITION定义时间值的处理方式CURL_TIMECOND_IFMODSINCE/CURL_TIMECOND_IFUNMODSINCE默认CURL_TIMECOND_NONE即 0相关枚举定义见 include/curl/curl.h#define CURL_TIMECOND_NONE 0L #define CURL_TIMECOND_IFMODSINCE 1L #define CURL_TIMECOND_IFUNMODSINCE 2L #define CURL_TIMECOND_LASTMOD 3LHTTP 请求头由 lib/http.c 根据条件类型生成CURL_TIMECOND_IFMODSINCE→ 发送If-Modified-Since头CURL_TIMECOND_IFUNMODSINCE→ 发送If-Unmodified-Since头CURL_TIMECOND_LASTMOD→ 发送Last-Modified头仅影响响应处理。若代码中已通过CURLOPT_HTTPHEADER显式设置了同名自定义头libcurl 会优先使用自定义头、不再重复生成见 lib/http.c。HTTP 时间头按 RFC 2616 要求使用 GMT 格式输出。与命令行工具的对应关系curl 命令行工具通过-z, --time-cond暴露同一能力见 docs/cmdline-opts/time-cond.md# 请求在指定时间之后修改过的资源 curl -z Wed 01 Sep 2021 12:18:00 https://example.com/ # 从文件读取时间戳 curl -z file $URL--time-cond与CURLOPT_TIMECONDITIONCURLOPT_TIMEVALUE一一对应CURLINFO_CONDITION_UNMET则对应命令行模式下curl -z时的内部判定结果。若需在命令行场景获得等价信息可结合-w %{http_code}观察 304 状态码。返回值与错误处理curl_easy_getinfo返回CURLE_OK (0)表示查询成功返回非零值表示出错具体错误码见 docs/libcurl/opts/libcurl-errors.md如传入非法句柄或选项类型不匹配等。需要强调的是该选项是查询型接口必须在curl_easy_perform完成之后调用在传输过程中调用拿到的可能是旧值。另外CURLINFO_CONDITION_UNMET是long类型选项传入的必须是long *指针与CURLINFO_STRING/CURLINFO_OFF_T等类型不可混用否则会因类型掩码不匹配导致CURLE_BAD_FUNCTION_ARGUMENT。实战建议缓存场景结合CURLOPT_TIMECONDITION做增量下载或缓存校验时务必在传输后检查CURLINFO_CONDITION_UNMET避免把 304 空响应误判为失败。条件与 Range 互斥从 lib/http.c 的源码可以看出设置了时间条件且同时设置 Range 时客户端侧不会模拟 304判定路径会有差异两者同时使用需谨慎。时间戳一致性CURLOPT_TIMEVALUE使用 Unix 秒数比较的是 UTC 时间构造时间戳时注意时区换算防止因时区偏移导致条件判断与预期不符。协议适用性官方文档声明该选项仅适用于 HTTP但仓库源码显示 FTPMDTM 路径与 FILEstat 路径同样会置位timecond标志因此在 FTP/FILE 场景下该选项同样具备参考价值。【免费下载链接】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),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →