ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

libcurl TELNET 协商选项配置指南:CURLOPT_TELNETOPTIONS 完整解析

libcurl TELNET 协商选项配置指南:CURLOPT_TELNETOPTIONS 完整解析 libcurl TELNET 协商选项配置指南CURLOPT_TELNETOPTIONS 完整解析【免费下载链接】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本文围绕 curl 开源仓库中 TELNET 协议实现的核心接口CURLOPT_TELNETOPTIONS讲解如何在 libcurl 中通过curl_slist向 Telnet 服务器传递协商选项终端类型、显示位置、环境变量等并结合 lib/telnet.c 与 lib/setopt.c 的源码揭示选项解析、协商状态机与底层发送逻辑。读完本文你将掌握该接口的完整用法、全部支持选项及其取值范围并能写出可实际运行的 TELNET 客户端代码。一、接口速览CURLOPT_TELNETOPTIONS是 libcurl 提供的、专门用于 TELNET 协议选项协商的 easy 接口选项自 libcurl 7.7 版本加入仅在 URL 协议为telnet://时生效。属性值选项名CURLOPT_TELNETOPTIONS适用协议TELNET引入版本7.7参数类型struct curl_slist *默认值NULL头文件include/curl/curl.h函数原型#include curl/curl.h CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TELNETOPTIONS, struct curl_slist *cmds);核心语义官方接口文档传入一个curl_slist链表链表中的每个字符串代表一条传给 Telnet 协商流程的变量格式必须为optionvalue重复调用本选项时最后一次设置会覆盖之前的所有设置将参数设为NULL可再次禁用本选项libcurl不会复制该链表调用方必须保证链表在传输完成之前一直存活。二、支持的 Telnet 选项接口文档明确声明 libcurl 支持TTYPE、XDISPLOC与NEW_ENV三个选项。而深入 lib/telnet.c 的解析逻辑可以发现实际实现还额外支持WS窗口大小与BINARY二进制传输开关两个选项它们在同一个循环中被解析。选项解析实现以下代码位于 lib/telnet.c是CURLOPT_TELNETOPTIONS的核心解析入口函数telnet_easy_initfor(head >#define CURL_TELOPT_BINARY 0 /* binary 8-bit data */ #define CURL_TELOPT_ECHO 1 /* echo */ #define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */ #define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */ #define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */ #define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */ #define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */ #define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */各选项深入说明TTYPE终端类型设置后将tn-subopt_ttype指向对应值并把us_preferred[CURL_TELOPT_TTYPE]置为CURL_YES表示本端希望在协商通过后以IAC SB TTYPE IS 值 IAC SE格式发送终端类型子选项。若值中包含 IAC 命令字节255会返回CURLE_BAD_FUNCTION_ARGUMENT若值长度超过 1000 字节则返回CURLE_SEND_ERRORlib/telnet.c。XDISPLOC显示位置处理逻辑与 TTYPE 完全对称设置tn-subopt_xdisploc并在协商成功后发送IAC SB XDISPLOC IS 值 IAC SElib/telnet.c。NEW_ENV环境变量每条选项以NAME,VALUE格式追加到tn-telnet_vars链表同时将us_preferred[CURL_TELOPT_NEW_ENVIRON]置为CURL_YES。协商成功后libcurl 会构造IAC SB NEW_ENVIRON IS ... IAC SE子选项其中变量名以CURL_NEW_ENV_VAR0开头、变量值以CURL_NEW_ENV_VALUE1作为分隔标记lib/telnet.c。WS窗口大小值必须形如宽x高宽高均为 0655350xffff范围内的数字。解析使用curlx_str_number与curlx_str_single语法不合法时返回CURLE_SETOPT_OPTION_SYNTAXlib/telnet.c。窗口尺寸最终会以网络字节序htons写入IAC SB NAWS w h IAC SE子选项lib/telnet.c。BINARY二进制模式默认情况下 libcurl 会将 BINARY 选项置为CURL_YES与历史版本行为保持一致见 lib/telnet.c传入BINARY1保持默认传入其他值解析为 0则同时关闭本端与对端的二进制协商偏好lib/telnet.c。注意两个容易踩坑的细节选项值不允许包含 IAC 字节bad_option检查见 lib/telnet.c源码注释明确说明这是为了禁止通过选项值注入命令字节若选项值包含非 ASCII 字符该条会被静默跳过str_is_nonascii检查用户名非 ASCII 时同理返回CURLE_BAD_FUNCTION_ARGUMENT。三、完整可运行示例接口文档给出了基础示例CURLOPT_TELNETOPTIONS.md这里将其补全为可直接编译的完整程序并同时演示 TTYPE、XDISPLOC 与 NEW_ENV 的组合用法#include stdio.h #include curl/curl.h int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; struct curl_slist *options NULL; /* 终端类型 */ options curl_slist_append(options, TTYPEvt100); /* 环境变量NAME,VALUE 形式逗号分隔 */ options curl_slist_append(options, NEW_ENVUSER,foobar); options curl_slist_append(options, NEW_ENVTERM,vt100); /* X 显示位置 */ options curl_slist_append(options, XDISPLOC:0.0); /* 窗口大小宽x高 */ options curl_slist_append(options, WS800x600); curl_easy_setopt(curl, CURLOPT_URL, telnet://example.com/); curl_easy_setopt(curl, CURLOPT_TELNETOPTIONS, options); result curl_easy_perform(curl); if(result ! CURLE_OK) fprintf(stderr, curl_easy_perform() failed: %s\n, curl_easy_strerror(result)); curl_easy_cleanup(curl); curl_slist_free_all(options); } return 0; }要点链表在curl_easy_perform结束后才释放满足 libcurl“不复制链表”的生命周期要求选项字符串必须形如KEYvalue缺少会被判定为语法错误返回CURLE_SETOPT_OPTION_SYNTAX官方文档示例中的USERfoobar需要注意USER 变量不需要也不能通过选项列表传递。当 URL 中携带了user:password凭据如telnet://user:passhost/时libcurl 会在 lib/telnet.c 中自动将用户名以USER,name形式注入NEW_ENV协商此时手动传入USER...反而会因“USER”长度4不匹配任何分支而返回CURLE_UNKNOWN_OPTION。四、底层原理选项如何进入协商流程1. 设置阶段仅保存指针在 lib/setopt.c 中CURLOPT_TELNETOPTIONS被归类为 slist 类型选项处理方式非常轻量#ifndef CURL_DISABLE_TELNET case CURLOPT_TELNETOPTIONS: /* * Set a linked list of telnet options */ s-telnet_options slist; break; #endif它只是把指针存进 easy handle 的配置区不拷贝链表内容——这正是文档要求“链表必须存活到传输结束”的原因。在 lib/setopt.c 的Curl_vsetopt中它与CURLOPT_HTTPHEADER、CURLOPT_QUOTE、CURLOPT_MAIL_RCPT等一样被统一分派到setopt_slist处理。2. 协商阶段RFC 1143 状态机libcurl 的 TELNET 实现遵循 RFC 1143 的协商规范lib/telnet.c为每个选项维护双方状态/* For negotiation compliant to RFC 1143 */ #define CURL_NO 0 #define CURL_YES 1 #define CURL_WANTYES 2 #define CURL_WANTNO 3 #define CURL_EMPTY 0 #define CURL_OPPOSITE 1struct TELNETlib/telnet.c为 256 个可能的选项各维护一组状态us/usq/us_preferred描述本端we/us意愿him/himq/him_preferred描述对端he/him意愿subnegotiation标记协商通过后需要发送的子选项。CURLOPT_TELNETOPTIONS解析结果写入us_preferred与subopt_*字段随后由send_negotiation()lib/telnet.c以IAC WILL/DO/WONT/DONT option三字节命令发起协商。3. 接收阶段子选项收集接收侧的状态机lib/telnet.c逐字节扫描输入流typedef enum { CURL_TS_DATA 0, CURL_TS_IAC, CURL_TS_WILL, CURL_TS_WONT, CURL_TS_DO, CURL_TS_DONT, CURL_TS_CR, CURL_TS_SB, /* sub-option collection */ CURL_TS_SE /* looking for sub-option end */ } TelnetReceive;收到IAC SB后进入子选项收集模式用 512 字节的subbuffer累积数据CURL_SB_ACCUM宏lib/telnet.c收到IAC SE后交给suboption()处理当服务器以DO TTYPE等方式请求时libcurl 将之前配置的 TTYPE/XDISPLOC/NEW_ENV/NAWS 子选项编码发送回去lib/telnet.c。4. 默认协商偏好即使未调用CURLOPT_TELNETOPTIONSlibcurl 也会默认请求 SGASuppress Go Ahead、BINARY 以及对端 ECHOlib/telnet.c其中 BINARY 可用BINARY选项关闭ECHO 因可能迫使服务器关闭连接而被特殊处理。五、命令行工具映射--telnet-optioncurl 命令行工具通过-t/--telnet-option optionvalue暴露同一能力可多次指定curl -t TTYPEvt100 -t NEW_ENVUSER,foobar -t WS800x600 telnet://example.com/工具侧实现位于 src/tool_getparam.c每次调用将参数追加到config-telnet_options链表case C_TELNET_OPTION: /* --telnet-option */ /* Telnet options */ err add2list(config-telnet_options, nextarg); break;随后在 src/config2setopts.c 中一次性映射到 libcurl 接口my_setopt_slist(curl, CURLOPT_TELNETOPTIONS, config-telnet_options);六、返回值与错误处理curl_easy_setopt(handle, CURLOPT_TELNETOPTIONS, list)返回CURLcode其中CURLE_OK (0)设置成功CURLE_UNKNOWN_OPTION选项名不匹配长度或拼写不对如误写为TTTYPE或完全不认识该选项CURLE_SETOPT_OPTION_SYNTAX选项缺少或WS的宽/高不是合法数字CURLE_BAD_FUNCTION_ARGUMENT选项值包含 IAC 字节或凭据用户名含非 ASCII 字符传输阶段返回CURLE_SEND_ERRORTTYPE/XDISPLOC 值超过 1000 字节等发送阶段错误传输阶段返回。注意解析错误发生在curl_easy_perform()执行时的 TELNET 协议初始化阶段telnet_easy_init而非curl_easy_setopt()调用时因此判断结果必须结合curl_easy_perform()的返回值与curl_easy_strerror()输出。七、与其他选项的关系CURLOPT_TELNETOPTIONS与 CURLOPT_QUOTE、CURLOPT_HTTPHEADER 同为 slist 类型接口内存管理约定一致列表不复制、需自行维护生命周期URL 中的user:password凭据会自动注入 NEW_ENV 的USER变量无需也不应通过选项列表重复指定若需在编译期裁剪 TELNET 支持可在构建时定义CURL_DISABLE_TELNET此时该选项在 lib/setopt.c 中会被整体禁用。八、小结CURLOPT_TELNETOPTIONS是 libcurl 暴露 TELNET 选项协商能力的唯一入口通过curl_slist以optionvalue格式配置 TTYPE、XDISPLOC、NEW_ENV以及实现额外支持的 WS、BINARYlibcurl 会在连接建立后按 RFC 1143 规范自动完成 WILL/DO 协商与子选项收发。掌握本接口需要同时留意三件事链表必须存活到传输结束、选项名与值格式必须严格匹配源码解析规则、错误码的返回时机在perform阶段。配合 lib/telnet.c 与 lib/arpa_telnet.h 阅读可完整还原从配置到协商的整个 TELNET 数据通路。【免费下载链接】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),仅供参考
返回列表