ARTICLE DETAIL

资讯详情

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

cpp-httplib 自定义 HTTP 方法:用 CustomRoute() 接入 WebDAV、UPnP 等扩展协议

cpp-httplib 自定义 HTTP 方法:用 CustomRoute() 接入 WebDAV、UPnP 等扩展协议 后端网络【免费下载链接】cpp-httplibA C header-only HTTP/HTTPS server and client library项目地址https://gitcode.com/GitHub_Trending/cp/cpp-httplib点击查看免费下载导读cpp-httplib 默认只识别GET、POST等内置 HTTP 方法收到未知方法如 WebDAV 的PROPFIND、UPnP 的SUBSCRIBE会直接以400 Bad Request拒绝。本篇指南讲解如何通过Server::CustomRoute()注册任意符合 RFC 9110 token 规范的扩展方法包括路径参数与正则匹配、流式读取请求体、配合OPTIONS通告能力以及注册失败时的is_valid()防护机制。读完你将能够在 cpp-httplib 之上实现 WebDAV/自定义协议服务端。背景为什么需要自定义方法HTTP 方法Method并非只有标准的那十个。RFC 4918WebDAV定义了PROPFIND、PROPPATCH、MKCOL、COPY、MOVE、LOCK、UNLOCK、REPORT等扩展方法UPnP 设备则常使用SUBSCRIBE做事件订阅。cpp-httplib 的处理策略是只接受注册过处理器的方法。对未注册的未知方法服务端在解析请求行时就判定无效并返回400 Bad Request。这一点可以从请求解析源码直接印证。在 httplib.h 的请求行解析逻辑中// A method outside the built-in set is accepted only when a handler has been // registered for it with CustomRoute(). const auto methods builtin_methods(); if (methods.find(req.method) methods.end() !find_custom_entry(req.method)) { output_error_log(Error::InvalidHTTPMethod, req); return false; }也就是说方法被接受与否完全取决于CustomRoute()是否注册过对应处理器路由分发阶段httplib.h同样只在find_custom_entry()找到匹配条目时才进入自定义方法分发否则最终落到res.status StatusCode::BadRequest_400。注册处理器本身就是让服务端接受该方法的开关。Basic usage注册一个自定义方法CustomRoute()的签名与内置的Get()/Post()保持一致第一个参数是方法名第二个是路径模式第三个是处理器回调svr.CustomRoute(PROPFIND, /dav/:id, [](const httplib::Request req, httplib::Response res) { // The request body is available as usual auto id req.path_params.at(id); res.status httplib::StatusCode::MultiStatus_207; res.set_content(build_multistatus(req.body), application/xml); });模式匹配与Get()完全一致/dav/:id这类路径参数会填入req.path_params也可直接使用正则表达式模式。仓库测试 test/test.cc 分别验证了路径参数/dav/:id匹配/dav/42并提取id 42与正则模式R(/dav-re/(\d))匹配/dav-re/123并捕获123两种写法。注册完成后处理器内部可以像普通请求一样访问req.body、req.headers并通过res设置状态码、响应头与响应体。上面示例中返回207 Multi-Statushttplib.h 中枚举为StatusCode::MultiStatus_207并附上application/xml的多状态文档就是 WebDAV 服务最常见的应答形态。用 OPTIONS 通告你的能力WebDAV 客户端在做任何实际操作前会先发送OPTIONS询问服务器的能力集合。cpp-httplib不会自动生成DAV:响应头也不会生成Allow头这两者需要你在OPTIONS处理器中自行返回。忽略这一点即使PROPFIND逻辑完全正确客户端也会因为看不到能力通告而拒绝继续交互。svr.Options(/dav/.*, [](const httplib::Request req, httplib::Response res) { res.set_header(DAV, 1); res.set_header(Allow, OPTIONS, GET, HEAD, PROPFIND, PROPPATCH, MKCOL); });DAV头的值1表示服务器支持 RFC 4918 定义的 WebDAV 第 1 级能力如果你的实现还覆盖了版本管理或访问控制需要按规范相应调整该值。Allow头应如实列出服务器实际支持的方法避免通告了未实现的方法。由于OPTIONS本身就是内置方法这里走的是Server::Options()httplib.h无需CustomRoute()。以流式方式读取请求体WebDAV 的PROPFIND/REPORT请求体常常是体积不小的 XML 文档。如果不想一次性把整个文档读进内存可以使用CustomRoute()的ContentReader重载——与Post()上的内容读取器重载行为一致httplib.hsvr.CustomRoute(REPORT, /dav/.*, [](const httplib::Request req, httplib::Response res, const httplib::ContentReader content_reader) { content_reader( { // Process it a chunk at a time return true; }); res.status httplib::StatusCode::MultiStatus_207; });回调按块接收数据每收到一块就调用一次 lambdadata/data_length指向当前块返回true表示继续读取返回false则中止。数据会在读取过程中被逐块消费不会在req.body中整体缓冲。需要注意一个与内置方法一致的细节内容读取器路由在请求没有请求体时也会触发。从 httplib.h 的路由逻辑可以看到只要注册了 content-reader 处理器即便请求没有Content-Length/Transfer-Encoding也会走内容读取路径——因为 RFC 4918 规定无请求体的PROPFIND等价于allprop查询。对应测试见 test/test.cc该测试确认了无请求体的REPORT请求不会落到 404。注册规则与校验Things to keep in mind使用CustomRoute()时有几条硬性约束全部在注册阶段强制执行方法名必须是合法的 HTTP tokenRFC 9110。is_token()的实现见 httplib.h方法名不能为空只能由字母数字以及!#$%*-.^_|~ 等 token 字符组成不允许空格、制表符、斜杠、逗号、冒号、括号或控制字符。内置方法不允许注册。builtin_methods()httplib.h包含GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH、PRI十个方法。前七个含PATCH由路由中的 if/else 链直接分发用CustomRoute()注册它们永远不可能被触发CONNECT、TRACE、PRI虽无对应分支但分别承载隧道建立、请求回显、HTTP/2 连接前言的协议级语义库不负责路由。这些方法应使用各自专属的注册函数Get()、Post()、Put()、Delete()、Options()、Patch()等。必须在调用listen()之前完成注册。注册被拒绝会立即使is_valid()返回falselisten()随之失败服务器根本不会启动——从机制上杜绝了启动了一个永远跑不起来的处理器。静态文件服务与 WebSocket 升级仍然只接受GET/HEAD。路由阶段 httplib.h 明确只在GET/HEAD时进入handle_file_request()自定义方法不会绕开这一限制。校验机制的底层实现注册校验集中在 httplib.h 的custom_entry_for_registration()if (!detail::fields::is_token(method) || builtin_methods().count(method)) { output_error_log(Error::InvalidHTTPMethod, nullptr); has_invalid_registration_ true; return nullptr; }一旦校验失败错误会被上报到错误日志器可通过set_error_logger()观察错误码为Error::InvalidHTTPMethod并且has_invalid_registration_被置位。该标志是粘性的——test/test.cc 的RejectionIsSticky测试证明即使先成功注册了PROPFIND随后一次失败的GET注册也会让整个服务器实例失效。Server::is_valid()的实现就是直接返回!has_invalid_registration_httplib.hSSLServer::is_valid()则在 TLS 上下文之外叠加了这一判断httplib.h。测试对注册规则的覆盖仓库测试 test/test.cc 对注册规则做了全面验证RejectsBuiltInMethods对十个内置方法逐一注册断言is_valid()与listen()均失败RejectsNonTokenMethods对空串、PRO PFIND、PROP\tFIND、PROP/FIND、PROP,FIND、PROP:FIND、PROP(FIND)、含控制字符的方法名逐一注册断言is_valid()失败AcceptsWebDavAndUpnpMethodsPROPFIND、PROPPATCH、MKCOL、COPY、MOVE、LOCK、UNLOCK、REPORT、SUBSCRIBE全部注册成功is_valid()为真ReportsRejectionToErrorLogger确认失败注册通过错误日志器上报Error::InvalidHTTPMethod。无请求体的自定义方法行为与边界WebDAV 的MKCOL创建集合通常不带请求体。内置Delete()的 content-reader 重载早已支持无请求体请求CustomRoute()保持了相同语义普通 handler 形式在无请求体时正常工作见 test/test.cc 的CustomRouteWithoutBody返回201 Createdcontent-reader 形式同样会触发。此外 test/test.cc 的CustomMethodWithoutFraming测试确认一个既无Content-Length也无Transfer-Encoding的裸PROPFIND请求会被立即应答返回207 Multi-Status而不会阻塞在等待 EOF 的读取上。实战一个最小的 WebDAV 轮廓把以上要素串起来一个可运行的 WebDAV 服务骨架如下#include httplib.h int main() { httplib::Server svr; // 1. 注册扩展方法必须在 listen() 之前 svr.CustomRoute(PROPFIND, /dav/:id, [](const httplib::Request req, httplib::Response res) { res.status httplib::StatusCode::MultiStatus_207; res.set_content(multistatus xmlns\DAV:\/, application/xml); }); svr.CustomRoute(MKCOL, /dav/:id, [](const httplib::Request req, httplib::Response res) { res.status httplib::StatusCode::Created_201; }); // 2. 用 OPTIONS 通告能力 svr.Options(/dav/.*, [](const httplib::Request req, httplib::Response res) { res.set_header(DAV, 1); res.set_header(Allow, OPTIONS, GET, HEAD, PROPFIND, MKCOL); }); // 3. 注册失败时 listen() 会直接失败先做防御性检查 if (!svr.is_valid()) { return 1; } svr.listen(0.0.0.0, 8080); }边界说明协议实现仍在库外cpp-httplib 的自定义方法能力止步于把方法路由到你的处理器。如果目标是完整实现 WebDAV以下几点需要自己实现生成207 Multi-Status的 XML 文档multistatus、response、propstat等元素结构及DAV:命名空间解析Depth请求头决定PROPFIND是仅查询当前资源还是递归子资源锁管理LOCK/UNLOCKlock-token、锁超时、锁冲突423 Locked等状态处理。正如文档所述协议本身在库之外CustomRoute()只是给你一条接入它的路径。关于注册处理器的更多基础可参考 S01. Register GET / POST / PUT / DELETE handlers对应英文版 S01。赞分享后端网络【免费下载链接】cpp-httplibA C header-only HTTP/HTTPS server and client library项目地址https://gitcode.com/GitHub_Trending/cp/cpp-httplib点击查看免费下载相关推荐WebDAV协议扩展如何实现自定义属性和方法的终极指南WebDAV协议扩展如何实现自定义属性和方法的终极指南 WebDAV协议作为HTTP的扩展提供了强大的文件管理和协作功能。本文将深入探讨WebDAV协议的自后端存储网络requests 怎么发送 MKCOL 等自定义 HTTP 动词使用 request() 方法对接 WebDAV 服务requests 怎么发送 MKCOL 等自定义 HTTP 动词使用 request 方法对接 WebDAV 服务 对接 WebDAV 类服务时经常会用到后端网络通信RabbitMQ扩展协议自定义协议支持RabbitMQ扩展协议自定义协议支持 在分布式系统中消息队列Message Queue扮演着至关重要的角色它能够解耦系统组件、提高系统的可扩展性和可后端消息队列消息路由上一篇探索ADASIS V3协议深入了解高级驾驶辅助系统的核心技术下一篇探索电商新纪元ECShop V4.1.16深度解析与推荐创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表