- 人工智能
- AI Agent
- 多模态
- 语音
- AI 应用
【免费下载链接】ten-framework
Open-source framework for conversational voice AI agents
本仓库(ten-framework)在
third_party/curl下以源码形式内置了 curl,本指南以仓库内的 ALTSVC.md 为骨架,结合 lib/altsvc.c、lib/altsvc.h、命令行选项文档与示例代码,系统讲解 curl 对Alt-Svc:HTTP 响应头的支持:如何开启编译开关、如何读懂并维护 Alt-Svc 缓存文件、如何用命令行与 libcurl API 启用该特性。读完本文,你将能够独立解释缓存文件的每一列含义、手动校验缓存行、并通过--alt-svc或CURLOPT_ALTSVC在自己的 HTTP/2、HTTP/3 客户端中落地 Alt-Svc 加速能力。
Alt-Svc 是什么
Alt-Svc(Alternative Services,替代服务)是 curl 对 HTTP 响应头Alt-Svc:的特性支持,其规范定义于 RFC 7838《HTTP Alternative Services》。当服务端希望告知客户端"除了当前这个源(origin)之外,还可以用另一个协议/主机/端口组合来访问我"时,会通过该响应头下发候选地址。客户端将其缓存下来,后续请求即可尝试直接连接替代端点,从而获得更优路径或更高协议版本(例如从 HTTP/2 平滑切换到 HTTP/3/QUIC)。
curl 对这一特性的落地包含三个层面:
- 解析层:识别并解析服务端返回的
Alt-Svc:响应头(见 lib/altsvc.c 中的Curl_altsvc_parse); - 缓存层:将解析结果持久化为磁盘上的纯文本缓存文件(对应本文主题——缓存文件格式);
- 查询层:后续连接时根据源(src)匹配替代端点,并在命中后直接使用(
Curl_altsvc_lookup)。
构建时启用 Alt-Svc
curl 的 Alt-Svc 支持由构建开关控制,在 configure 阶段显式启用:
./configure --enable-alt-svc值得注意的前提:自 7.73.0 起该特性默认开启,因此大多数现代发行版与内置构建无需额外指定此选项。与之对应,源码层面存在一个总开关宏CURL_DISABLE_ALTSVC——当同时定义了CURL_DISABLE_HTTP或CURL_DISABLE_ALTSVC时,lib/altsvc.c 与 lib/altsvc.h 中的实现会被整体编译排除,公共 API 退化为空操作(见altsvc.h末尾的 disabled 分支)。
此外,缓存查询所支持的协议版本与编译选项强相关:从 lib/altsvc.c 的Curl_altsvc_init()可以看到,默认启用的版本位掩码为CURLALTSVC_H1,并在构建了USE_HTTP2时追加CURLALTSVC_H2、在构建了ENABLE_QUIC时追加CURLALTSVC_H3。也就是说:Alt-Svc 缓存中能实际"使用"哪些替代协议,取决于你的 curl 编译进了哪些 HTTP 版本。
命令行用法:--alt-svc
命令行工具侧由--alt-svc <file name>选项启用(仅适用于 HTTPS 协议),其完整定义见 docs/cmdline-opts/alt-svc.d:
curl --alt-svc svc.txt https://example.com关键行为(源自该选项文档与 src/tool_getparam.c 的实现):
- 若指定的文件名已存在,curl 会先加载其中的缓存条目;传输结束后,若缓存有变更,会重新写回同一文件;
- 传入零长度文件名(空字符串)时,curl 只在内存中维护缓存,不加载也不落盘;
- 该选项可多次使用:curl 会依次加载所有指定文件,但只有最后一个文件用于保存;
- 若构建未包含 Alt-Svc 特性,使用该选项会直接返回"libcurl 不支持"错误(
PARAM_LIBCURL_DOESNT_SUPPORT),命令参数表中该选项注册于 src/tool_getparam.c; - 实际生效路径为 src/tool_operate.c:把
config->altsvc字符串通过CURLOPT_ALTSVC注入到 easy handle。
在 HTTP/3 场景中,该选项常与 QUIC 端点配合使用,例如 docs/HTTP3.md 中的示例:
curl --alt-svc altsvc.cache https://quic.aiortc.org/Alt-Svc 缓存文件格式
缓存文件是纯文本、逐行一条记录的格式,每行由9 个以空格分隔的字段组成。
官方示例行
h2 quic.tech 8443 h3-22 quic.tech 8443 "20190808 06:18:37" 0 09 个字段逐一拆解
| 字段序号 | 含义 |
|---|---|
| 1 | 源 origin 的 ALPN 协议标识(如h2) |
| 2 | 源 origin 的主机名 |
| 3 | 源 origin 的端口号 |
| 4 | 目标(替代)主机的 ALPN 协议标识 |
| 5 | 目标主机的主机名 |
| 6 | 目标主机的端口号 |
| 7 | 条目的过期时间,必须用双引号包裹,格式为"YYYYMMDD HH:MM:SS",时区为 GMT |
| 8 | 布尔值(1 或 0),表示该条目是否设置了persist(持久化)标记 |
| 9 | 整数优先级值(当前未使用,写 0 即可) |
对照示例行可得到完整的语义:源 origin 为h2://quic.tech:8443,其替代端点为同一主机 8443 端口上的h3-22协议(HTTP/3 草案版本标识),过期时间为 2019-08-08 06:18:37(GMT),未标记 persist,优先级为 0。
文件格式的源码级约束
解析器对每一行的尺寸与取值有硬性限制,超出即整行丢弃(见 lib/altsvc.c):
- 单行最大长度:4095 字符(
MAX_ALTSVC_LINE); - 主机名字段最长:512 字符(
MAX_ALTSVC_HOSTLEN); - ALPN 标识字段最长:10 字符(
MAX_ALTSVC_ALPNLEN); - 日期字段缓冲区:64 字符(
MAX_ALTSVC_DATELEN)。
加载逻辑(altsvc_load)以sscanf严格匹配九字段布局(lib/altsvc.c),只有恰好解析出 9 个字段才插入缓存链表。此外:
- 行首空白会被跳过,以
#开头的行作为注释被忽略(lib/altsvc.c); - 从源码的
alpn2alpnid()(lib/altsvc.c)可以推断:当前读取器只识别h1、h2、h3三种 ALPN 标识,其余字符串(包括示例中遗留的h3-22这类草案标识)会被视为未知协议并跳过该条目; - 主机名匹配是大小写不敏感的,且忽略主机名末尾的单个点号(
hostcompare,见 lib/altsvc.c); - 日期解析经由
Curl_getdate_capped完成(lib/altsvc.c),写回时由altsvc_out按YYYYMMDD HH:MM:SS(4 位年份、GMT)重新格式化(lib/altsvc.c)。
写回时附加的头部注释
libcurl 落盘保存时,会先写入两行说明性注释(lib/altsvc.c):
# Your alt-svc cache. https://curl.se/docs/alt-svc.html # This file was generated by libcurl! Edit at your own risk.保存过程采用临时文件 + 原子重命名策略(Curl_fopen写临时文件、Curl_rename替换目标文件),避免中途崩溃导致缓存文件损坏(lib/altsvc.c)。
libcurl API 编程实践
除了命令行,开发者可以直接在 libcurl 编程中使用两个专属选项(定义于 include/curl/curl.h):
CURLOPT_ALTSVC(选项号 287):字符串参数,指定缓存文件名;空字符串表示仅在内存中维护;CURLOPT_ALTSVC_CTRL(选项号 286):长整型参数,位掩码,控制允许使用的替代协议版本与文件行为。
控制位掩码 CURLALTSVC_*
位定义见 include/curl/curl.h:
| 宏 | 值 | 含义 |
|---|---|---|
CURLALTSVC_H1 | 1<<3 | 允许使用 h1 替代协议 |
CURLALTSVC_H2 | 1<<4 | 允许使用 h2 替代协议 |
CURLALTSVC_H3 | 1<<5 | 允许使用 h3 替代协议 |
CURLALTSVC_READONLYFILE | 1<<2 | 缓存文件只读,不写回磁盘 |
其中READONLYFILE的语义可以从源码确认:当该位被置位(或未指定保存文件名)时,Curl_altsvc_save直接返回、不做任何磁盘写入(lib/altsvc.c)。此外,Curl_altsvc_ctrl要求掩码非零,否则返回CURLE_BAD_FUNCTION_ARGUMENT(lib/altsvc.c)。
最小可运行示例
仓库内置了完整的 API 示例 docs/examples/altsvc.c,核心逻辑如下:
#include <curl/curl.h> CURL *curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); /* 将替代端点缓存到该文件 */ curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc.txt"); /* 限定允许使用的替代协议版本 */ curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, (long) CURLALTSVC_H1|CURLALTSVC_H2|CURLALTSVC_H3); CURLcode res = curl_easy_perform(curl); if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); curl_easy_cleanup(curl); }缓存条目的生命周期:解析、匹配与过期
理解缓存文件格式后,再看一看条目在内存中的完整生命周期,这有助于判断手动编辑缓存文件时的正确姿势。
响应头解析:Curl_altsvc_parse逐项解析Alt-Svc:响应头值(lib/altsvc.c)。其中有两个值得注意的细节:
- 响应头值中的
clear是一个"魔法关键字":遇到它时,curl 会清空该源 origin 对应的全部缓存条目(altsvc_flush,见 lib/altsvc.c); - 每条替代项支持两个可选参数:
ma(max-age,以秒为单位,默认 24 小时,即 86400 秒)与persist(值为 1 时置位)。过期时间expires = maxage + 当前时间(lib/altsvc.c),而不是直接采用服务端给定的绝对时间。
查询匹配:Curl_altsvc_lookup遍历缓存链表(lib/altsvc.c),匹配条件为:源 ALPN id、源主机(忽略末尾点号、大小写不敏感)、源端口三者一致,且目标 ALPN id 在CURLALTSVC_CTRL传入的版本位掩码内;同时,已过期条目会在遍历时被即时删除,保证缓存不残留僵尸记录。
字段含义对齐:缓存文件第 8 字段persist与响应头中的persist参数相对应——当服务端标记持久化时,缓存条目即使跨进程也会被保留;第 9 字段优先级目前仅存储、不参与调度(lib/altsvc.c),文档亦明确标注"当前未使用"。
已知限制与待办项
原文档在 TODO 一节列出了三个未完成事项,结合源码可进一步确认其现状:
- 多个响应头的
clear覆盖问题:当一次响应中出现多个Alt-Svc:响应头、且其中一个值为clear时,规范要求该clear应覆盖(清除)其余全部条目,当前实现尚未对此场景做整体合并处理; Age:响应头的使用:按 RFC 7838 第 3.1 节,缓存年龄应综合考虑Age:响应头的取值,当前实现尚未纳入(lib/altsvc.c 的注释即对应此待办);CURLALTSVC_IMMEDIATELY支持:立即生效模式的位标志尚未实现,当前 include/curl/curl.h 中只有READONLYFILE、H1、H2、H3四个位。
这些限制意味着:在 HTTP/3 调研与客户端开发中,若遇到服务端下发多个 Alt-Svc 头或依赖Age:的场景,需要留意 curl 当前版本(本仓库内 vendored 的 curl)的行为边界。
在仓库中的位置与延伸阅读
本仓库以三方源码形式内置 curl(位于third_party/curl/,构建入口见 BUILD.gn),相关文档与代码清单如下:
- 本文骨架文档:docs/ALTSVC.md
- 核心实现:lib/altsvc.c、lib/altsvc.h
- 命令行选项定义:docs/cmdline-opts/alt-svc.d
- 编程示例:docs/examples/altsvc.c
- 公共头文件常量:include/curl/curl.h
- HTTP/3 下的典型用法:docs/HTTP3.md
若要进一步验证缓存文件的读写行为,可重点阅读altsvc_add(加载行)、altsvc_out(写出行)与Curl_altsvc_parse(响应头解析)三处函数,它们共同构成了 Alt-Svc 特性在磁盘与协议两侧的完整闭环。
- 人工智能
- AI Agent
- 多模态
- 语音
- AI 应用
【免费下载链接】ten-framework
Open-source framework for conversational voice AI agents
相关推荐
curl/libcurl 的 CURLOPT_ALTSVC 选项:Alt-Svc 缓存文件读写完全指南
curl/libcurl 的 CURLOPT_ALTSVC 选项:Alt Svc 缓存文件读写完全指南 本篇技术指南聚焦 libcurl 的 CURLOPT_A
CLI网络通信curl `--alt-svc` 选项实战:开启 Alt-Svc 缓存解析与 HTTP 协议升级
curl alt svc 选项实战:开启 Alt Svc 缓存解析与 HTTP 协议升级 导读 本文聚焦 curl 命令行工具中启用 HTTP Alt Svc
CLI网络通信curl HSTS 支持详解:基于 libcurl 的内存缓存、缓存文件格式与 C/C++/命令行接入方式
curl HSTS 支持详解:基于 libcurl 的内存缓存、缓存文件格式与 C/C++/命令行接入方式 导读 HTTP Strict Transport S
人工智能AI Agent多模态语音AI 应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考