3

我已经开始使用(稳定版本 0.10.1)开发 HTTP 服务器cpp-netlib,并且从可用文档中我不确定如何在服务器处理程序中访问 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);
}

但是根据 in 的定义,not_quite_pod_request_baseheaders.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的包装器?至少在我看来,a 似乎更容易使用。vectorcpp-netlibmultimap

更新

我还快速浏览了 POCO 库,但不明白它们的身份验证类是否也仅用于客户端会话或服务器?如果有人可以对此提供提示,也许我仍然可以切换到 POCO,如果这会让生活变得更轻松。

4

1 回答 1

2

您所指的特征适用于客户端请求中的标头,用于 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也许)。但是接口改进是使与客户端请求/响应一起使用的代码也与服务器请求/响应对象一起使用。

于 2015-03-23T15:54:22.470 回答