msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified Han script) (Boost Beast Translation "
"(zh_Hans))\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-25 17:01+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Chinese (Simplified Han script) <https://"
"insights.cppalliance.org/weblate/projects/boost-beast-documentation-zh_Hans/"
"doc-qbk-08-design-1-http-message-qbk/zh_Hans/>\n"
"Language: zh_Hans\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 2026.5\n"

#. type: section title
#: 12
msgid "HTTP Message Container __video__"
msgstr "HTTP 消息容器 __video__"

#. type: paragraph
#: 14
msgid ""
"The following video presentation was delivered at [@https://cppcon.org/ "
"CppCon] in 2017. The presentation provides a simplified explanation of the "
"design process for the HTTP message container used in Beast. The slides and "
"code used are available in the [@https://github.com/vinniefalco/CppCon2017 "
"GitHub repository]."
msgstr ""
"以下视频演示是在 2017 年的 [@https://cppcon.org/ CppCon] 上发表的。该演示简要"
"介绍了 Beast 中使用的 HTTP 消息容器的设计过程。演示所用的幻灯片和代码可在 "
"[@https://github.com/vinniefalco/CppCon2017 GitHub 仓库] 中找到。"

#. type: paragraph
#: 31
msgid ""
"In this section we describe the problem of modeling HTTP messages and "
"explain how the library arrived at its solution, with a discussion of the "
"benefits and drawbacks of the design choices. The goal for creating a "
"message model is to create a container with value semantics, possibly "
"movable and/or copyable, that contains all the information needed to "
"serialize, or all of the information captured during parsing. More formally, "
"given:"
msgstr ""
"在本节中，我们将探讨 HTTP 消息建模所面临的挑战，并阐述该库是如何推导出最终解"
"决方案的，同时也会深入剖析这些设计选择的利弊。构建消息模型的核心目标，是打造"
"一个具备值语义（value semantics）的容器（支持移动和/或复制），使其能够囊括序"
"列化所需的全部信息，或是完整保留解析过程中捕获的所有数据。从更严谨的层面来说"
"，给定："

#. type: list
#: 38
msgid "* `m` is an instance of an HTTP message container"
msgstr "* `m` 是 HTTP 消息容器的一个实例"

#. type: list
#: 40
msgid "* `x` is a series of octets describing a valid HTTP message in"
msgstr "* `x` 是一系列字节（octets），用于描述一个有效的 HTTP 消息"

#. type: list
#: 43
msgid "* `S(m)` is a serialization function which produces a series of octets"
msgstr "* `S(m)` 是一个序列化函数，用于生成一系列字节（octets）"

#. type: list
#: 46
msgid "* `P(x)` is a parsing function which produces a message container from"
msgstr "* `P(x)` 是一个解析函数，用于从……生成一个消息容器"

#. type: paragraph
#: 49
msgid "These relations are true:"
msgstr "以下关系成立："

#. type: list
#: 51
msgid "* `S(m) == x`"
msgstr "* `S(m) == x`"

#. type: list
#: 53
msgid "* `P(S(m)) == m`"
msgstr "* `P(S(m)) == m`"

#. type: paragraph
#: 55
msgid ""
"We would also like our message container to have customization points "
"permitting the following: allocator awareness, user-defined containers to "
"represent header fields, and user-defined types and algorithms to represent "
"the body. And finally, because requests and responses have different fields "
"in the ['start-line], we would like the containers for requests and "
"responses to be represented by different types for function overloading."
msgstr ""
"此外，我们还希望消息容器提供自定义扩展点，以实现以下功能：支持分配器感知（"
"allocator awareness）、允许使用用户自定义的容器来表示首部字段，以及支持使用用"
"户自定义的类型和算法来表示消息体。最后，由于请求和响应的起始行（start-line）"
"包含不同的字段，我们希望分别使用不同的类型来表示请求和响应的容器，从而支持函"
"数重载。"

#. type: paragraph
#: 63
msgid "Here is our first attempt at declaring some message containers:"
msgstr "这是我们首次尝试声明一些消息容器："

#. type: paragraph
#: 97
msgid ""
"These containers are capable of representing everything in the model of HTTP "
"requests and responses described in __rfc7230__. Request and response "
"objects are different types. The user can choose the container used to "
"represent the fields. And the user can choose the [*Body] type, which is a "
"concept defining not only the type of `body` member but also the algorithms "
"used to transfer information in and out of that member when performing "
"serialization and parsing."
msgstr ""
"这些容器能够完整地表达 RFC 7230 中描述的 HTTP 请求和响应模型。请求对象和响应"
"对象是两种不同的类型。用户可以选择用于表示首部字段的容器。此外，用户还可以选"
"择 `Body` 类型，该类型不仅定义了 `body` 成员的类型，还规定了在序列化和解析过"
"程中，信息进出该成员所使用的算法。"

#. type: paragraph
#: 105
msgid ""
"However, a problem arises. How do we write a function which can accept an "
"object that is either a request or a response? As written, the only obvious "
"solution is to make the message a template type. Additional traits classes "
"would then be needed to make sure that the passed object has a valid type "
"which meets the requirements. These unnecessary complexities are bypassed by "
"making each container a partial specialization: ``` /// An HTTP message "
"template<bool isRequest, class Fields, class Body> struct message;"
msgstr ""
"然而，问题随之而来。如何编写一个既能接受请求对象又能接受响应对象的函数呢？按"
"照当前的写法，最显而易见的解决方案是将消息类型设为模板参数。这样一来，还需要"
"额外的特征类（traits classes）来确保传入的对象具有符合要求的有效类型。为了避"
"免这些不必要的复杂性，我们可以将每个容器设计为偏特化（partial specialization"
"）：```/// An HTTP message template<bool isRequest, class Fields, class "
"Body> struct message;"

#. type: paragraph
#: 116
msgid ""
"/// An HTTP request template<class Fields, class Body> struct message<true, "
"Fields, Body> {"
msgstr ""
"/// 一个 HTTP 请求模板<class Fields, class Body> struct message<true, "
"Fields, Body> {"

#. type: paragraph
#: 126
msgctxt "126"
msgid "};"
msgstr "};"

#. type: paragraph
#: 128
msgid ""
"/// An HTTP response template<bool isRequest, class Fields, class Body> "
"struct message<false, Fields, Body> {"
msgstr ""
"/// 一个 HTTP 响应模板<bool isRequest, class Fields, class Body> struct "
"message<false, Fields, Body> {"

#. type: paragraph
#: 138
msgctxt "138"
msgid "}; ```"
msgstr "}; ```"

#. type: paragraph
#: 141
msgid ""
"Now we can declare a function which takes any message as a parameter: ``` "
"template<bool isRequest, class Fields, class Body> void f(message<isRequest, "
"Fields, Body>& msg); ```"
msgstr ""
"现在，我们可以声明一个能够接受任意消息作为参数的函数了：``` template<bool "
"isRequest, class Fields, class Body> void f(message<isRequest, Fields, Body>"
"& msg); ```"

#. type: paragraph
#: 147
msgid ""
"This function can manipulate the fields common to requests and responses. If "
"it needs to access the other fields, it can use overloads with partial "
"specialization, or in C++17 a `constexpr` expression: ``` template<bool "
"isRequest, class Fields, class Body> void f(message<isRequest, Fields, Body>"
"& msg) {"
msgstr ""
"该函数可以处理请求和响应共有的字段。如果需要访问其他字段，则可以使用基于偏特"
"化的重载，或者在 C++17 中使用 constexpr 表达式：``` template<bool isRequest, "
"class Fields, class Body> void f(message<isRequest, Fields, Body>& msg) {"

#. type: paragraph
#: 162
msgid "} ```"
msgstr "} ```"

#. type: paragraph
#: 165
msgid ""
"Often, in non-trivial HTTP applications, we want to read the HTTP header and "
"examine its contents before choosing a type for [*Body]. To accomplish this, "
"there needs to be a way to model the header portion of a message. And we'd "
"like to do this in a way that allows functions which take the header as a "
"parameter, to also accept a type representing the whole message (the "
"function will see just the header part). This suggests inheritance, by "
"splitting a new base class off of the message: ``` /// An HTTP message "
"header template<bool isRequest, class Fields> struct header; ```"
msgstr ""
"通常，在非平凡的 HTTP 应用程序中，我们希望在为 [*Body] 选择类型之前，先读取 "
"HTTP 头部并检查其内容。为了实现这一点，需要有一种方法来对消息的头部部分进行建"
"模。并且，我们希望以这样的方式来实现：让那些将头部作为参数的函数，也能够接受"
"代表整个消息的类型（函数只会看到头部部分）。这表明可以通过从 message 中分离出"
"一个新的基类来使用继承：``` /// An HTTP message header template<bool "
"isRequest, class Fields> struct header; ```"

#. type: paragraph
#: 178
msgid ""
"Code which accesses the fields has to laboriously mention the `fields` "
"member, so we'll not only make `header` a base class but we'll make a "
"quality of life improvement and derive the header from the fields for "
"notational convenience. In order to properly support all forms of "
"construction of [*Fields] there will need to be a set of suitable "
"constructor overloads (not shown): ``` /// An HTTP request header "
"template<class Fields> struct header<true, Fields> : Fields {"
msgstr ""
"访问字段的代码不得不反复显式引用 `fields` 成员，这显得十分繁琐。因此，我们不"
"仅将 `header` 作为基类，还会为了书写便利进行一项优化：让 `header` 直接从 "
"`fields` 派生。为了能够正确支持对 [*Fields] 的所有构造形式，还需要提供一组合"
"适的构造函数重载（此处未展示）：``` /// An HTTP request header "
"template<class Fields> struct header<true, Fields> : Fields {"

#. type: paragraph
#: 192
msgctxt "192"
msgid "};"
msgstr "};"

#. type: paragraph
#: 194
msgctxt "194"
msgid ""
"/// An HTTP response header template<class Fields> struct header<false, "
"Fields> : Fields {"
msgstr "/// 一个 HTTP 响应头部 template struct header<false, Fields> : Fields {"

#. type: paragraph
#: 201
msgctxt "201"
msgid "};"
msgstr "};"

#. type: paragraph
#: 203
msgid ""
"/// An HTTP message template<bool isRequest, class Fields, class Body> "
"struct message : header<isRequest, Fields> {"
msgstr ""
"/// 一个 HTTP 消息 template<bool isRequest, class Fields, class Body> struct "
"message : header<isRequest, Fields> {"

#. type: paragraph
#: 211
msgctxt "211"
msgid "};"
msgstr "};"

#. type: paragraph
#: 213
msgid "```"
msgstr "```"

#. type: paragraph
#: 215
msgid ""
"Note that the `message` class now has a constructor allowing messages to be "
"constructed from a similarly typed `header`. This handles the case where the "
"user already has the header and wants to make a commitment to the type for "
"[*Body]. A function can be declared which accepts any header: ``` "
"template<bool isRequest, class Fields> void f(header<isRequest, Fields>& msg)"
"; ```"
msgstr ""
"请注意，`message` 类现在拥有一个构造函数，允许从类型相同的 `header` 构造消息"
"。这解决了用户已经拥有头部，并希望为 [*Body] 确定具体类型的情况。我们可以声明"
"一个能够接受任意头部的函数： ``` template<bool isRequest, class Fields> void "
"f(header<isRequest, Fields>& msg); ```"

#. type: paragraph
#: 224
msgid ""
"Until now we have not given significant consideration to the constructors of "
"the `message` class. But to achieve all our goals we will need to make sure "
"that there are enough constructor overloads to not only provide for the "
"special copy and move members if the instantiated types support it, but also "
"allow the fields container and body container to be constructed with "
"arbitrary variadic lists of parameters. This allows the container to fully "
"support allocators."
msgstr ""
"到目前为止，我们还没有对 `message` 类的构造函数给予足够的重视。但为了实现所有"
"目标，我们必须确保提供足够多的构造函数重载。这不仅需要在实例化的类型支持时提"
"供特殊的拷贝和移动成员，还需要允许使用任意的可变参数列表来构造字段容器和主体"
"容器。这使得容器能够完全支持分配器。"

#. type: paragraph
#: 232
msgid ""
"The solution used in the library is to treat the message like a `std::pair` "
"for the purposes of construction, except that instead of `first` and "
"`second` we have the `Fields` base class and `message::body` member. This "
"means that single-argument constructors for those fields should be "
"accessible as they are with `std::pair`, and that a mechanism identical to "
"the pair's use of `std::piecewise_construct` should be provided. Those "
"constructors are too complex to repeat here, but interested readers can view "
"the declarations in the corresponding header file."
msgstr ""
"库中采用的解决方案是：在构造 `message` 时，将其视作 `std::pair` 来处理。不同"
"的是，原本 `std::pair` 中的 `first` 和 `second` 在这里被替换成了 `Fields` 基"
"类和 `message::body` 成员。这意味着，这些字段的单参数构造函数应当像 "
"`std::pair` 一样易于调用，并且需要提供一套与 `std::pair` 的 "
"`std::piecewise_construct` 完全相同的机制。由于这些构造函数的实现较为复杂，这"
"里不再赘述，感兴趣的读者可以直接查阅相应头文件中的声明。"

#. type: paragraph
#: 241
msgid ""
"There is now significant progress with our message container but a stumbling "
"block remains. There is no way to control the allocator for the "
"`std::string` members. We could add an allocator to the template parameter "
"list of the header and message classes, use it for those strings. This is "
"unsatisfying because of the combinatorial explosion of constructor "
"variations needed to support the scheme. It also means that request messages "
"could have [*four] different allocators: two for the fields and body, and "
"two for the method and target strings. A better solution is needed."
msgstr ""
"尽管我们的消息容器已经取得了显著进展，但仍面临一个棘手的问题：目前无法控制 "
"`std::string` 成员的分配器。虽然可以在 `header` 和 `message` 类的模板参数列表"
"中添加一个分配器来管理这些字符串，但这并不是一个令人满意的方案。因为这需要引"
"入数量庞大的构造函数重载来支持该机制，导致组合爆炸。此外，这也意味着请求消息"
"可能会拥有多达四种不同的分配器：其中两个分别用于字段和主体，另外两个则用于方"
"法（method）和目标（target）字符串。因此，我们需要寻找一个更好的解决方案。"

#. type: paragraph
#: 250
msgid ""
"To get around this we make an interface modification and then add a "
"requirement to the [*Fields] type. First, the interface change: ``` /// An "
"HTTP request header template<class Fields> struct header<true, Fields> : "
"Fields {"
msgstr ""
"为了解决这个问题，我们首先对接口进行修改，然后对 `Fields` 类型增加一项要求。"
"首先是接口层面的改动：``` /// 一个 HTTP 请求头部 template<class Fields> "
"struct header<true, Fields> : Fields {"

#. type: paragraph
#: 267
msgid "private:"
msgstr "private:"

#. type: paragraph
#: 269
msgctxt "269"
msgid "};"
msgstr "};"

#. type: paragraph
#: 271
msgctxt "271"
msgid ""
"/// An HTTP response header template<class Fields> struct header<false, "
"Fields> : Fields {"
msgstr "/// 一个 HTTP 响应头部 template struct header<false, Fields> : Fields {"

#. type: paragraph
#: 279
msgctxt "279"
msgid "}; ```"
msgstr "}; ```"

#. type: paragraph
#: 282
msgid ""
"The start-line data members are replaced by traditional accessors using non-"
"owning references to string buffers. The method is stored using a simple "
"integer instead of the entire string, for the case where the method is "
"recognized from the set of known verb strings."
msgstr ""
"起始行（start-line）的数据成员被替换成传统的访问器（accessors），它们通过不持"
"有所有权的引用来指向字符串缓冲区。此外，对于能从已知动词字符串集合中识别出的"
"方法（method），系统直接使用一个简单的整数来存储，而不再保存完整的字符串。"

#. type: paragraph
#: 287
msgid ""
"Now we add a requirement to the fields type: management of the corresponding "
"string is delegated to the [*Fields] container, which can already be "
"allocator aware and constructed with the necessary allocator parameter via "
"the provided constructor overloads for `message`. The delegation "
"implementation looks like this (only the response header specialization is "
"shown): ``` /// An HTTP response header template<class Fields> struct "
"header<false, Fields> : Fields {"
msgstr ""
"对 `Fields` 类型增加一项要求：将对应字符串的管理委托给 `Fields` 容器。该容器"
"本身已具备分配器感知能力，且可通过 `message` 提供的构造函数重载，使用必要的分"
"配器参数进行构造。委托的实现方式如下（仅展示响应头部的特化版本）：``` /// 一"
"个 HTTP 响应头部 template<class Fields> struct header<false, Fields> : "
"Fields {"

#. type: paragraph
#: 312
msgctxt "312"
msgid "}; ```"
msgstr "}; ```"

#. type: paragraph
#: 315
msgid ""
"Now that we've accomplished our initial goals and more, there are a few more "
"quality of life improvements to make. Users will choose different types for "
"`Body` far more often than they will for `Fields`. Thus, we swap the order "
"of these types and provide a default. Then, we provide type aliases for "
"requests and responses to soften the impact of using `bool` to choose the "
"specialization:"
msgstr ""
"初步目标已超额达成，接下来还需进行一些提升易用性的改进。由于用户为 `Body` 选"
"择自定义类型的频率远高于为 `Fields` 选择，因此将这两者的模板参数顺序互换，并"
"为 `Fields` 提供默认类型。随后，为请求和响应提供类型别名，以缓解直接使用 "
"`bool` 来选择特化版本带来的不便："

#. type: paragraph
#: 322
msgid ""
"``` /// An HTTP header template<bool isRequest, class Body, class Fields = "
"fields> struct header;"
msgstr ""
"``` /// 一个 HTTP 头部 template<bool isRequest, class Body, class Fields = "
"fields> struct header;"

#. type: paragraph
#: 327
msgid ""
"/// An HTTP message template<bool isRequest, class Body, class Fields = "
"fields> struct message;"
msgstr ""
"/// 一个 HTTP 消息 template<bool isRequest, class Body, class Fields = "
"fields> struct message;"

#. type: paragraph
#: 331
msgid ""
"/// An HTTP request template<class Body, class Fields = fields> using "
"request = message<true, Body, Fields>;"
msgstr ""
"/// 一个 HTTP 请求 template<class Body, class Fields = fields> using request "
"= message<true, Body, Fields>;"

#. type: paragraph
#: 335
msgid ""
"/// An HTTP response template<class Body, class Fields = fields> using "
"response = message<false, Body, Fields>; ```"
msgstr ""
"/// 一个 HTTP 响应 template<class Body, class Fields = fields> using "
"response = message<false, Body, Fields>; ```"

#. type: paragraph
#: 340
msgid ""
"This allows concise specification for the common cases, while allowing for "
"maximum customization for edge cases: ``` request<string_body> req;"
msgstr ""
"这样既能以简洁的方式满足常见需求，又能为边缘情况提供最大程度的定制空间：``` "
"request<string_body> req;"

#. type: paragraph
#: 345
msgid "response<file_body> res; ```"
msgstr "response<file_body> res; ```"

#. type: paragraph
#: 348
msgid ""
"This container is also capable of representing complete HTTP/2 messages. Not "
"because it was explicitly designed for, but because the IETF wanted to "
"preserve message compatibility with HTTP/1. Aside from version specific "
"fields such as Connection, the contents of HTTP/1 and HTTP/2 messages are "
"identical even though their serialized representation is considerably "
"different. The message model presented in this library is ready for HTTP/2."
msgstr ""
"该容器同样能够表示完整的 HTTP/2 消息。这并非因为它是为此而专门设计的，而是因"
"为 IETF 希望保持与 HTTP/1 的消息兼容性。除了像 `Connection` 这类特定于版本的"
"字段之外，HTTP/1 和 HTTP/2 消息的内容是完全相同的，尽管它们的序列化表示形式存"
"在显著差异。因此，本库中展示的消息模型已经为 HTTP/2 做好了准备。"

#. type: paragraph
#: 355
msgid ""
"In conclusion, this representation for the message container is well thought "
"out, provides comprehensive flexibility, and avoids the necessity of "
"defining additional traits classes. User declarations of functions that "
"accept headers or messages as parameters are easy to write in a variety of "
"ways to accomplish different results, without forcing cumbersome SFINAE "
"declarations everywhere."
msgstr ""
"综上所述，这种消息容器的表示方式经过深思熟虑，提供了全面的灵活性，并且免去了"
"定义额外特征类（traits classes）的必要。用户声明接受头部或消息作为参数的函数"
"时，可以通过多种方式轻松编写，以实现不同的目的，而无需在代码中到处使用繁琐的 "
"SFINAE 声明。"
