ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

libwebsockets 最小 HTTP 服务器自定义 MIME 类型示例:在 TEN-framework 中为挂载点扩展文件后缀映射

libwebsockets 最小 HTTP 服务器自定义 MIME 类型示例:在 TEN-framework 中为挂载点扩展文件后缀映射 人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载libwebsocketslws是 TEN-framework 内嵌于 third_party/libwebsockets 目录的底层网络库之一其官方 minimal-examples 系列中的minimal-http-server-mimetypes示例展示了如何在不修改 libwebsockets 源码的前提下为一个 HTTP 挂载点mount注册文件后缀 → MIME 类型的额外映射。本指南以该示例为主线逐步拆解其构建方式、运行效果、C 语言结构体初始化细节并结合仓库内lws_get_mimetype()的实现说明用户自定义 MIME 与内置 MIME 表之间的优先级关系最后给出等价 JSON 配置lwsws 风格的写法。读完本文你将掌握在 lws 中为任意后缀如.tar.bz2、.wasm、.mp4添加Content-Type映射的完整方法。示例解决的问题内置 MIME 表之外的扩展名libwebsockets 服务静态文件时会依据文件扩展名决定响应头中的Content-Type。它内置了一张常见映射表.html、.js、.css、.png、.svg、.gz、.json等但不可能覆盖所有后缀。例如本示例中的test.tar.bz2——lws 内置表并不认识.bz2若不额外注册该文件将无法被正确服务。minimal-http-server-mimetypes示例与基础版minimal-http-server几乎完全相同唯一差别就是在挂载点定义中通过extra_mimetypes字段教会了服务器后缀.bz2对应 MIME 类型application/x-bzip2。示例页面mount-origin/index.html中放置了一个指向 test.tar.bz2 的下载链接用于直观验证这一行为。构建与运行示例位于仓库 third_party/libwebsockets/minimal-examples/http-server/minimal-http-server-mimetypes目录下包含minimal-http-server-mimetypes.c全部服务器逻辑单文件CMakeLists.txtCMake 构建脚本mount-origin/服务器文档根目录含index.html、404 页面、logo 与测试用test.tar.bz2。构建方式与 libwebsockets 其他 minimal 示例一致$ cmake . make生成的二进制名为lws-minimal-http-server-mimetypes定义于 CMakeLists.txt。该构建脚本通过require_lws_config()检查了两项编译期特性LWS_ROLE_H1HTTP/1.x 角色与LWS_WITH_SERVER服务器能力只有安装的 libwebsockets 具备这两项配置时才会真正编译链接。启动服务器$ ./lws-minimal-http-server-mimetypes [2018/03/04 09:30:02:7986] USER: LWS minimal http server | visit http://localhost:7681 [2018/03/04 09:30:02:7986] NOTICE: Creating Vhost default port 7681, 1 protocols, IPv6 on随后访问http://localhost:7681页面会显示 Hello from the minimal http server mimetypes example点击其中的test.tar.bz2链接即可下载该文件。关键点在于浏览器能正确识别并下载正是因为服务器为该文件返回了Content-Type: application/x-bzip2。源码剖析一个结构体注册一种 MIME 映射自定义 MIME 的核心全部浓缩在 minimal-http-server-mimetypes.c 中的两个静态结构体里。1. 用lws_protocol_vhost_options描述映射关系static const struct lws_protocol_vhost_options pvo_mime { NULL, /* next pvo linked-list */ NULL, /* child pvo linked-list */ .bz2, /* file suffix to match */ application/x-bzip2 /* mimetype to use */ };lws_protocol_vhost_options是 libwebsockets 中通用的键值对链表节点定义于 include/libwebsockets/lws-context-vhost.h四个字段分别为字段含义next指向下一个同层节点多个映射时串成链表options指向该节点的子选项链表此处 MIME 映射用不到name键名即文件后缀如.bz2value键值即 MIME 类型如application/x-bzip2注意后缀写法name需包含点号前缀.bz2这与内置表中.html、.png的命名风格一致。想要注册多个扩展名只需声明多个lws_protocol_vhost_options节点并把前一个的next指向后一个即可。2. 把映射挂到 mount 的extra_mimetypes字段static const struct lws_http_mount mount { /* .mount_next */ NULL, /* .mountpoint */ /, /* .origin */ ./mount-origin, /* .def */ index.html, /* .protocol */ NULL, /* .cgienv */ NULL, /* .extra_mimetypes */ pvo_mime, // 关键行 /* .interpret */ NULL, /* .cgi_timeout */ 0, /* .cache_max_age */ 0, /* .auth_mask */ 0, /* .cache_reusable */ 0, /* .cache_revalidate */ 0, /* .cache_intermediaries */ 0, /* .origin_protocol */ LWSMPRO_FILE, /* .mountpoint_len */ 1, /* .basic_auth_login_file */ NULL, };struct lws_http_mount的完整定义见 lws-context-vhost.h。本例中与 MIME 主题相关的字段extra_mimetypes指向lws_protocol_vhost_options链表的头节点即上文定义的pvo_mime。该字段的注释即为 optional linked-list of mimetype mappings。origin_protocol LWSMPRO_FILE声明该挂载点从文件系统目录./mount-origin提供服务LWSMPRO_FILE是enum lws_mount_protocols中的取值之一其余还有LWSMPRO_HTTP反向代理、LWSMPRO_CGI交给 CGI 处理、LWSMPRO_CALLBACK等。mountpoint /、origin ./mount-origin、def index.html分别指定 URL 挂载路径、磁盘目录和默认首页文件名。3. 在main()中装配并运行memset(info, 0, sizeof info); info.port 7681; info.mounts mount; info.error_document_404 /404.html; info.options LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; context lws_create_context(info); if (!context) { lwsl_err(lws init failed\n); return 1; } while (n 0 !interrupted) n lws_service(context, 0); lws_context_destroy(context);要点说明info.mounts mount将挂载点挂到 vhost 的 URL 命名空间上一个 vhost 可通过mount_next串联多个 mount。info.options启用了LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE即强制输出一组安全响应头如Content-Security-Policy、X-Content-Type-Options等安全最佳实践头示例页面中的strict-csp.svg正是对这一策略的呼应。日志级别默认LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE可通过-d命令行参数覆盖lws_cmdline_option解析后调用lws_set_log_level如需看到匹配到用户自定义 MIME这类lwsl_info级别的日志需要更高的日志级别且 lws 需以 DEBUG 构建。事件循环lws_service(context, 0)持续分发事件直至收到SIGINTsigint_handler将interrupted置 1后优雅退出并销毁 context。底层原理lws_get_mimetype()的三级查找顺序MIME 匹配逻辑实现在 lib/roles/http/server/server.c 的lws_get_mimetype()函数中整体是一个先用户、后内置、再兜底的优先级链遍历用户自定义映射extra_mimetypes链表逐个比较请求文件名尾部的后缀。命中即返回对应的value并打印match to user mimetype日志。若某个节点的name以*开头如*它不会立即参与匹配而是被暂存为fallback_mimetype。回退到内置 MIME 表server_mimetypes[]静态数组同文件 server.c内置了 19 条常见映射如.html → text/html、.js → text/javascript、.svg → image/svgxml、.json → application/json等。后缀比较使用strcasecmp大小写不敏感。使用*兜底映射若存在*定义且前两级均未命中返回该兜底 MIME若*的值为空串则文件仍可被服务但不附带Content-Type头。从源码看*通配是最后兜底而非最高优先这与直觉略有不同先命中的普通后缀映射永远优先于通配。此外若一个后缀既不在内置表也不在自定义表中且没有*兜底lws_get_mimetype()返回NULL对应的文件将不被服务——这是 lws 有意为之的安全措施详见下文。为什么 lws 拒绝未知后缀README.lwsws.md 明确解释了这一设计正常情况下文件后缀必须匹配内置 MIME 表或 extra-mimetypes 之一否则文件不会被服务。这带来一层额外安全防护即使存在路径绕过漏洞导致挂载目录被穿透lws 也不会把诸如/etc/passwd之类的任意文件吐给客户端没有合法后缀映射就不会输出内容。因此为自定义文件类型注册 MIME 映射不仅是功能需求也是让 lws 愿意服务该文件的前提条件。等价做法用 JSON 配置声明额外 MIMElwsws 风格extra_mimetypes不仅能在 C 代码里以结构体链表形式提供也支持在 lwswslibwebsockets 的 Web 服务器JSON 配置中按挂载点声明。配置解析代码位于 lib/roles/http/server/lejp-conf.c路径模式vhosts[].mounts[].extra-mimetypes.*解析时同样会构建lws_protocol_vhost_options链表并挂入m.extra_mimetypes见 lejp-conf.c。JSON 写法示例取自 README.lwsws.mdmounts: [ { mountpoint: /, origin: file:///var/www/mysite.com, extra-mimetypes: { .zip: application/zip, .doc: text/evil } } ]需要任何后缀都允许服务时可声明通配条目extra-mimetypes: { *: }效果是已知后缀仍走内置表或普通映射返回Content-Type完全未知的后缀则被服务但不携带Content-Type响应头对应源码中fallback_mimetype为空串的分支。与 TEN-framework 的关系及延伸阅读在 TEN-framework 仓库中libwebsockets 以内嵌第三方依赖形式位于 third_party/libwebsockets其官方 minimal-examples 全部保留在minimal-examples/目录下含http-server/、ws-server/、raw-proxy/等众多系列是学习 lws 编程模型的第一手资料。本示例所演示的 mount 机制、lws_context_creation_info装配方式与 vhost 概念在 lws 的服务器/客户端架构中具有通用性挂载点mount体系见struct lws_http_mount文档注释 lws-context-vhost.h其中还包含 CGI 环境变量cgienv、解释器interpret、缓存策略cache_max_age等、Basic Authbasic_auth_login_file等能力MIME 优先级与安全策略见 server.c 的 lws_get_mimetype() 及 README.lwsws.md 的安全说明挂载点 JSON 配置的完整字段清单见 lejp-conf.c 的路径定义表。若需为更多后缀如.wasm、.m3u8、.mp4、.yaml添加映射仅需仿照pvo_mime再声明节点并串入链表即可——这正是本示例以最小代码量演示可扩展性的用意所在。赞分享人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载相关推荐TEN Framework websocket_server_python用 Python 扩展示例在 TEN 应用中搭建 WebSocket 服务器TEN Framework websocket_server_python用 Python 扩展示例在 TEN 应用中搭建 WebSocket 服务器 本文以人工智能AI Agent多模态语音AI 应用TEN Framework simple_http_server_cpp 扩展详解用 libwebsockets 把 HTTP 请求桥接为 TEN 命令TEN Framework simple_http_server_cpp 扩展详解用 libwebsockets 把 HTTP 请求桥接为 TEN 命令 本篇人工智能AI Agent多模态语音AI 应用BLOOM-3B模型深度解析30亿参数如何实现45种自然语言与12种编程语言支持 BLOOM 3B模型深度解析30亿参数如何实现45种自然语言与12种编程语言支持 想要了解如何用30亿参数的AI模型支持45种自然语言和12种编程语言吗上一篇GIST-small-Embedding-v0-openmind开发者完全手册 - 终极API参考与最佳实践指南 下一篇流畅网络FluidNetGoogle开源的深度学习优化工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表