我已经开始使用cpp-netlib
(稳定版本0.10.1)开发HTTP服务器,并且从可用文档中我不知道如何在服务器处理程序中访问HTTP请求标头。我知道可以使用这样的包装器来完成它:
void operator()(async_server::request const &Request, async_server::connection_ptr pConnection)
{
http::impl::request_headers_wrapper<http::tags::http_async_server> Headers = headers(Request);
}
但是根据not_quite_pod_request_base
中headers.hpp
的定义,这实际上是对的向量,如果我想要搜索,则难以搜索找出是否存在某个标题。如果没有其他选项,那么我当然会坚持这一点,但是看起来最初它的意思是多图,至少从headers_container.hpp
判断:
namespace boost { namespace network {
template <class Tag>
struct headers_container {
typedef std::multimap<
typename string<Tag>::type,
typename string<Tag>::type
> type;
};
} // namespace network
} // namespace boost
所以任何人都可以指出为什么会有这样的重新定义,或者我错过了某种方式来实际获取multimap
或者是vector
“首选”工作方式的包装器标题为cpp-netlib
?至少在我看来,multimap
似乎更容易使用。
更新
我还快速浏览了POCO库,但无法理解他们的身份验证类是否仅适用于客户端会话或服务器?如果有人能给出一个暗示,也许我仍然可以切换到POCO,如果这样可以让生活变得更轻松。
答案 0 :(得分:1)
您所引用的特征适用于客户端请求中的标头,用于cpp-netlib中的客户端实现。有一些工作正在完成(不完整),以使得从服务器中的请求获取标头与从客户端请求/响应对象获取请求相同。
服务器端的头是对的向量的原因是空间和时间方面的“效率”。如果您可以支付在服务器处理程序上创建多图的费用,那么您应该这样做。通过高效的方式有效地处理请求中的标题的常用模式是始终对您要查找的标题进行线性扫描,并在它们进入时对其进行处理。类似于此:
string content_type, content_length;
for (const auto& header : request.headers) {
if (header.name == "Content-Type") content_type = header.value;
if (header.name == "Content-Length") content_length = header.value;
if (!content_type.empty() && !content_length.empty()) break;
}
如果您的应用程序需要此级别的标头处理,您可以使用某种模式(可能是std::map<string, std::function<void(const std::string&)>>
)对此进行概括。
一般来说,迭代向量列表不应该花费太多时间。如果标题数量很大(O(10,000))那么您还有其他问题。这里的权衡是在内存局部性之间(向量具有连续元素而不是具有通常在内存的不同部分中随机分配的元素的映射)和有效查找(对数时间在一定大小之后才真正有意义)。
我完全接受了便利性受到影响的观点。也许不同的数据结构在这里会有所帮助(也许是boost::flat_map
)。但是,接口改进将使得与客户端请求/响应一起使用的代码也可以与服务器请求/响应对象一起使用。