libcurl CURLINFO_RESPONSE_CODE:获取传输完成后的最后响应码(HTTP/FTP/SMTP/LDAP)
2026/9/10 0:06:34 网站建设 项目流程

libcurl CURLINFO_RESPONSE_CODE:获取传输完成后的最后响应码(HTTP/FTP/SMTP/LDAP)

【免费下载链接】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

CURLINFO_RESPONSE_CODE是 libcurl 中通过curl_easy_getinfo()读取传输结果的关键信息项之一:传输结束后,用它可以取回服务器返回的最后一个响应码,涵盖 HTTP 状态码、FTP 应答码、SMTP 应答码与 LDAP(仅 OpenLDAP)结果码。本文以 CURLINFO_RESPONSE_CODE 官方手册页 为主体,结合本仓库的公开头文件与核心源码,完整讲清该选项的定义、语义、版本演进、跨协议的取值来源,以及与代理 CONNECT 应答码选项的边界,帮助你在集成 libcurl 的程序中正确、可靠地解析服务器响应。

一、选项定义与调用方式

官方手册给出的标准调用签名如下:

#include <curl/curl.h> CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_RESPONSE_CODE, long *codep);

从当前仓库的公开头文件可以确认其枚举定义:

/* include/curl/curl.h */ CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2,

两个值得注意的细节(见 include/curl/curl.h):

  • 该枚举值是CURLINFO_LONG + 2,即它属于long 类型的 getinfo 项,因此必须传入一个long *指针;
  • 它是CURLINFO枚举中的第 2 个信息项(仅次于CURLINFO_EFFECTIVE_URL),属于 libcurl 最早期、最核心的结果查询接口之一。

调用时序上,该选项应当在curl_easy_perform()完成(无论返回CURLE_OK还是错误码)之后再查询,因为响应码只在传输过程中由服务器应答填充。

二、返回值的语义:按协议区分含义

官方手册(CURLINFO_RESPONSE_CODE.md)的 DESCRIPTION 部分说明:传入一个long指针,即可收到最后收到的HTTP、FTP、SMTP 或 LDAP(仅 OpenLDAP 后端)响应码。若尚未收到任何服务器响应码,存储的值为0

结合仓库源码,可以按协议列出该值的具体含义与各协议在实现中的写入点:

协议返回值含义源码写入位置
HTTP最后一条状态行的 HTTP 状态码(如 200、301、404、416)lib/http.c
FTP最后一次 FTP 应答码lib/ftp.c
SMTP最后一次 SMTP 应答码lib/smtp.c
LDAP最后一条 LDAP 操作结果码(仅 OpenLDAP 后端)lib/openldap.c、lib/openldap.c

从源码结构看,四种协议写入的是同一个存储字段data->info.httpcode。例如:

/* lib/smtp.c */>int main(void) { CURL *curl = curl_easy_init(); if(curl) { CURLcode result; curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); result = curl_easy_perform(curl); if(result == CURLE_OK) { long response_code; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); } curl_easy_cleanup(curl); } }

实际集成时建议做三点强化:

  1. 检查 getinfo 自身的返回码curl_easy_getinfo()返回CURLcodeCURLE_OK (0)表示成功,非零表示出错(详见libcurl-errors(3)手册页)。类型不匹配(例如传入int *却声明为 LONG 类型项)会返回CURLE_BAD_FUNCTION_ARGUMENT
  2. 区分 0 与有效码。手册明确"未收到响应码时存值为 0",所以response_code == 0不能按 200 处理,通常意味着传输在收到应答前就失败(如连接错误、TLS 失败)。
  3. 结合CURLOPT_FAILONERROR使用。若设置了CURLOPT_FAILONERROR,HTTP 4xx/5xx 会使curl_easy_perform()返回CURLE_HTTP_RETURNED_ERROR,此时CURLINFO_RESPONSE_CODE仍然保留了具体状态码,可用于区分 401 与 404 等细粒度逻辑。

四、名称演进与版本历史

手册 NOTES 与 front matter 记录了完整的版本脉络:

事件版本
原名CURLINFO_HTTP_CODE引入7.4.1
更名为CURLINFO_RESPONSE_CODE(当前名)7.10.8
支持 SMTP 响应码7.25.0
支持 OpenLDAP 结果码7.81.0

头文件中保留了向后兼容的宏别名,这也是老代码无需修改即可编译的原因(include/curl/curl.h):

/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as CURLINFO_HTTP_CODE */ #define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE

front matter 中还声明了该选项适用的协议集合:HTTPFTPSMTPLDAP,与正文描述一致。

五、源码视角:响应码如何被解析与存储

理解底层写入链路有助于解释一些边界行为(如"0 值"何时出现)。

1. 查询入口curl_easy_getinfo()的 long 类型分发在 lib/getinfo.c:

switch(info) { case CURLINFO_RESPONSE_CODE: *param_longp =>k->httpcode = ((p[0] - '0') * 100) + ((p[1] - '0') * 10) + ...

源码中还包含若干协议细节处理,例如按 HTTP/0.9 语义在无状态行时按 200 处理(lib/http.c)、304 Not Modified 的专门赋值(lib/http.c),以及 416(Range Not Satisfiable)、417(Expectation Failed)在请求流中的特殊分支(lib/http.c、lib/http.c)。

3. 与代理的交互。当经过 HTTP 代理时,lib/cf-h1-proxy.c 会先把data->info.httpcode清零(注释说明"它可能被上一段使用过"),随后代理对 CONNECT 的应答会被同时写入httpproxycodehttpcode(见 lib/cf-h1-proxy.c、lib/cf-h1-proxy.c)。这解释了为什么官方特别强调:代理的 CONNECT 应答应读取CURLINFO_HTTP_CONNECTCODE,而不是本选项

六、与 CURLINFO_HTTP_CONNECTCODE 的对比

两个选项经常混淆,差异对照如下:

对比项CURLINFO_RESPONSE_CODECURLINFO_HTTP_CONNECTCODE
读取字段data->info.httpcodedata->info.httpproxycode
语义最后收到的服务器响应码(HTTP/FTP/SMTP/LDAP)代理对 CONNECT 请求的响应码
适用协议HTTP、FTP、SMTP、LDAP仅 HTTP(经代理)
典型值200、304、404、416200(隧道建立成功)
未收到时00
引入版本7.10.8(原名 7.4.1)7.10.7

CURLINFO_HTTP_CONNECTCODE的完整说明见 CURLINFO_HTTP_CONNECTCODE.md。在"HTTPS over 代理"场景中,一个健壮的客户端应同时检查两者:CONNECT 码确认隧道握手成功,CURLINFO_RESPONSE_CODE再确认目标站点的最终状态。

七、实践要点小结

  • 该选项是long类型信息项,查询参数必须为long *,且建议在curl_easy_perform()之后调用;
  • 返回 0 表示"没有收到响应码",不应与 200 混淆;
  • 启用CURLOPT_FOLLOWLOCATION跟随重定向时,"最后收到的响应码"即为重定向链最终一跳的状态码,中间跳的 3xx 不会保留;
  • 需要区分目标站点响应与代理 CONNECT 响应时,分别使用CURLINFO_RESPONSE_CODECURLINFO_HTTP_CONNECTCODE,两者的取值字段与语义在源码层面是相互独立的(见 lib/getinfo.c);
  • 老代码中的CURLINFO_HTTP_CODE与当前选项等价,由 include/curl/curl.h 中的宏别名保证兼容,新代码应优先使用CURLINFO_RESPONSE_CODE

八、返回值

curl_easy_getinfo()返回一个CURLcode指示成功或失败:CURLE_OK (0)表示一切正常;非零表示发生错误(参见libcurl-errors(3))。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询