求判定:CURLINFO_CONDITION_UNMET 使用指南)
libcurl 條件請(qǐng)求判定CURLINFO_CONDITION_UNMET 使用指南【免費(fèi)下載鏈接】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項(xiàng)目地址: https://gitcode.com/GitHub_Trending/cu/curl本篇技術(shù)指南圍繞 libcurl 提供的CURLINFO_CONDITION_UNMET信息選項(xiàng)展開(kāi)講解如何通過(guò)curl_easy_getinfo判斷一次基于時(shí)間條件的 HTTP/FTP/FILE 傳輸是否因條件未滿足而被跳過(guò)例如服務(wù)器返回 304 或資源未按預(yù)期更新并結(jié)合當(dāng)前倉(cāng)庫(kù)源碼剖析其底層實(shí)現(xiàn)與判定邏輯。讀完本文你將掌握條件請(qǐng)求的完整搭配方案、返回值語(yǔ)義與實(shí)戰(zhàn)代碼寫(xiě)法。什么是 CURLINFO_CONDITION_UNMETCURLINFO_CONDITION_UNMET是 libcurl 的一個(gè)信息info選項(xiàng)用于在傳輸結(jié)束后查詢上一次請(qǐng)求設(shè)置的時(shí)間條件time condition是否未被滿足。它屬于long類(lèi)型的 getinfo 選項(xiàng)枚舉值為CURLINFO_LONG 35定義見(jiàn) include/curl/curl.h自 curl 7.19.4 版本起加入僅適用于 HTTP 協(xié)議。典型場(chǎng)景當(dāng)客戶端發(fā)送帶If-Modified-Since之類(lèi)的條件請(qǐng)求服務(wù)器判定資源未更新于是不返回文檔正文。此時(shí)curl_easy_perform仍然返回CURLE_OK畢竟請(qǐng)求本身成功了但下載到的數(shù)據(jù)量為零。如果不對(duì)返回內(nèi)容加以區(qū)分很容易把資源未更新誤當(dāng)成下載失敗或空文件。CURLINFO_CONDITION_UNMET正是用來(lái)消解這種歧義的它告訴你這次成功的空傳輸?shù)降资菞l件未滿足還是本來(lái)就該這樣。接口原型#include curl/curl.h CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_CONDITION_UNMET, long *unmet);傳入一個(gè)指向long的指針curl_easy_getinfo會(huì)把結(jié)果寫(xiě)入該變量返回1之前請(qǐng)求中設(shè)置的條件未匹配。即你沒(méi)有拿到數(shù)據(jù)是因?yàn)橘Y源不滿足你提出的時(shí)間條件返回0條件已滿足或從未設(shè)置條件傳輸正常進(jìn)行。此外即使你沒(méi)有顯式設(shè)置時(shí)間條件只要服務(wù)器以HTTP 304狀態(tài)碼響應(yīng)例如客戶端主動(dòng)發(fā)送了自定義的If-Match-*請(qǐng)求頭該選項(xiàng)同樣會(huì)返回 1。底層實(shí)現(xiàn)flag 如何被置位getinfo 的讀取邏輯curl_easy_getinfo對(duì)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; }代碼要點(diǎn)CURLOPT_TIMEVALUE設(shè)置對(duì)比用的時(shí)間戳Unix 秒數(shù)示例中1577833200即 2020-01-01 00:00:00 UTCCURLOPT_TIMECONDITION設(shè)置為CURL_TIMECOND_IFMODSINCE表示只在資源修改時(shí)間晚于該時(shí)間戳?xí)r才傳輸curl_easy_perform返回CURLE_OK后用CURLINFO_CONDITION_UNMET查詢條件是否未滿足unmet為 1 時(shí)打印NOT fulfilled說(shuō)明傳輸被條件跳過(guò)為 0 時(shí)打印fulfilled說(shuō)明資源滿足條件、數(shù)據(jù)已正常接收。配套選項(xiàng)與時(shí)間條件語(yǔ)義CURLINFO_CONDITION_UNMET本身只負(fù)責(zé)查詢結(jié)果條件請(qǐng)求的建立依賴(lài)兩個(gè) setopt 選項(xiàng)詳見(jiàn) docs/libcurl/opts/CURLOPT_TIMECONDITION.md選項(xiàng)作用取值CURLOPT_TIMEVALUE指定對(duì)比用時(shí)間戳Unix 時(shí)間秒long 類(lèi)型CURLOPT_TIMECONDITION定義時(shí)間值的處理方式CURL_TIMECOND_IFMODSINCE/CURL_TIMECOND_IFUNMODSINCE默認(rèn)CURL_TIMECOND_NONE即 0相關(guān)枚舉定義見(jiàn) include/curl/curl.h#define CURL_TIMECOND_NONE 0L #define CURL_TIMECOND_IFMODSINCE 1L #define CURL_TIMECOND_IFUNMODSINCE 2L #define CURL_TIMECOND_LASTMOD 3LHTTP 請(qǐng)求頭由 lib/http.c 根據(jù)條件類(lèi)型生成CURL_TIMECOND_IFMODSINCE→ 發(fā)送If-Modified-Since頭CURL_TIMECOND_IFUNMODSINCE→ 發(fā)送If-Unmodified-Since頭CURL_TIMECOND_LASTMOD→ 發(fā)送Last-Modified頭僅影響響應(yīng)處理。若代碼中已通過(guò)CURLOPT_HTTPHEADER顯式設(shè)置了同名自定義頭libcurl 會(huì)優(yōu)先使用自定義頭、不再重復(fù)生成見(jiàn) lib/http.c。HTTP 時(shí)間頭按 RFC 2616 要求使用 GMT 格式輸出。與命令行工具的對(duì)應(yīng)關(guān)系curl 命令行工具通過(guò)-z, --time-cond暴露同一能力見(jiàn) docs/cmdline-opts/time-cond.md# 請(qǐng)求在指定時(shí)間之后修改過(guò)的資源 curl -z Wed 01 Sep 2021 12:18:00 https://example.com/ # 從文件讀取時(shí)間戳 curl -z file $URL--time-cond與CURLOPT_TIMECONDITIONCURLOPT_TIMEVALUE一一對(duì)應(yīng)CURLINFO_CONDITION_UNMET則對(duì)應(yīng)命令行模式下curl -z時(shí)的內(nèi)部判定結(jié)果。若需在命令行場(chǎng)景獲得等價(jià)信息可結(jié)合-w %{http_code}觀察 304 狀態(tài)碼。返回值與錯(cuò)誤處理curl_easy_getinfo返回CURLE_OK (0)表示查詢成功返回非零值表示出錯(cuò)具體錯(cuò)誤碼見(jiàn) docs/libcurl/opts/libcurl-errors.md如傳入非法句柄或選項(xiàng)類(lèi)型不匹配等。需要強(qiáng)調(diào)的是該選項(xiàng)是查詢型接口必須在curl_easy_perform完成之后調(diào)用在傳輸過(guò)程中調(diào)用拿到的可能是舊值。另外CURLINFO_CONDITION_UNMET是long類(lèi)型選項(xiàng)傳入的必須是long *指針與CURLINFO_STRING/CURLINFO_OFF_T等類(lèi)型不可混用否則會(huì)因類(lèi)型掩碼不匹配導(dǎo)致CURLE_BAD_FUNCTION_ARGUMENT。實(shí)戰(zhàn)建議緩存場(chǎng)景結(jié)合CURLOPT_TIMECONDITION做增量下載或緩存校驗(yàn)時(shí)務(wù)必在傳輸后檢查CURLINFO_CONDITION_UNMET避免把 304 空響應(yīng)誤判為失敗。條件與 Range 互斥從 lib/http.c 的源碼可以看出設(shè)置了時(shí)間條件且同時(shí)設(shè)置 Range 時(shí)客戶端側(cè)不會(huì)模擬 304判定路徑會(huì)有差異兩者同時(shí)使用需謹(jǐn)慎。時(shí)間戳一致性CURLOPT_TIMEVALUE使用 Unix 秒數(shù)比較的是 UTC 時(shí)間構(gòu)造時(shí)間戳?xí)r注意時(shí)區(qū)換算防止因時(shí)區(qū)偏移導(dǎo)致條件判斷與預(yù)期不符。協(xié)議適用性官方文檔聲明該選項(xiàng)僅適用于 HTTP但倉(cāng)庫(kù)源碼顯示 FTPMDTM 路徑與 FILEstat 路徑同樣會(huì)置位timecond標(biāo)志因此在 FTP/FILE 場(chǎng)景下該選項(xiàng)同樣具備參考價(jià)值?!久赓M(fèi)下載鏈接】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項(xiàng)目地址: https://gitcode.com/GitHub_Trending/cu/curl創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考