|
8 | 8 | // |
9 | 9 |
|
10 | 10 | = HTTP Messages |
| 11 | + |
| 12 | +Every HTTP interaction is a message exchange: a client sends a request, |
| 13 | +a server sends a response. This library gives you three complementary |
| 14 | +components for working with messages: |
| 15 | + |
| 16 | +* **Containers** build and inspect the start line and headers |
| 17 | +* **Serializer** transforms a container and body data into bytes for the wire |
| 18 | +* **Parser** transforms bytes from the wire into a container and body data |
| 19 | + |
| 20 | +These components are designed to work together but remain independently |
| 21 | +useful. You can build a message with a container, serialize it for |
| 22 | +transmission, and parse the reply — or use any one in isolation. |
| 23 | + |
| 24 | +== Containers Hold Headers, Not Bodies |
| 25 | + |
| 26 | +An HTTP message consists of a start line, header fields, and an optional |
| 27 | +body. This library keeps the body separate from the container. The |
| 28 | +`request` and `response` types hold only the start line and headers in |
| 29 | +their serialized wire format. This avoids parameterizing on body type |
| 30 | +and keeps the containers simple: |
| 31 | + |
| 32 | +[source,cpp] |
| 33 | +---- |
| 34 | +request req(method::get, "/api/users"); |
| 35 | +req.set(field::host, "example.com"); |
| 36 | +req.set(field::accept, "application/json"); |
| 37 | +
|
| 38 | +// buffer() returns the serialized start line + headers |
| 39 | +std::cout << req.buffer(); |
| 40 | +---- |
| 41 | + |
| 42 | +Body data flows through the serializer or parser instead. |
| 43 | + |
| 44 | +== The Serializer and Parser Are Persistent Objects |
| 45 | + |
| 46 | +Both the serializer and parser allocate a fixed block of memory at |
| 47 | +construction and reuse it across every message on a connection. This |
| 48 | +eliminates per-message allocation and makes resource usage predictable. |
| 49 | +Create one of each when a connection is established and keep them alive |
| 50 | +for its duration: |
| 51 | + |
| 52 | +[source,cpp] |
| 53 | +---- |
| 54 | +// One parser and one serializer per connection |
| 55 | +request_parser pr; |
| 56 | +serializer sr(cfg); |
| 57 | +
|
| 58 | +pr.reset(); |
| 59 | +
|
| 60 | +while (connection_open) |
| 61 | +{ |
| 62 | + pr.start(); |
| 63 | + // ... parse a request ... |
| 64 | + // ... serialize a response ... |
| 65 | +} |
| 66 | +---- |
| 67 | + |
| 68 | +== Two-Sided Interfaces |
| 69 | + |
| 70 | +The serializer and parser each expose two sides: |
| 71 | + |
| 72 | +[cols="1,2,2"] |
| 73 | +|=== |
| 74 | +| |Input Side |Output Side |
| 75 | + |
| 76 | +|**Serializer** |
| 77 | +|Sink — accepts a container and body data from the caller |
| 78 | +|Stream — emits serialized HTTP bytes for writing to a socket |
| 79 | + |
| 80 | +|**Parser** |
| 81 | +|Stream — accepts raw bytes read from a socket |
| 82 | +|Source — yields a parsed container and body data to the caller |
| 83 | +|=== |
| 84 | + |
| 85 | +This two-sided design follows naturally from their role as transformers: |
| 86 | +the serializer converts structured data into bytes, and the parser |
| 87 | +converts bytes into structured data. Neither side performs I/O directly. |
| 88 | +You feed data in on one side and pull results out the other. |
| 89 | + |
| 90 | +== Sans-I/O at Every Layer |
| 91 | + |
| 92 | +None of these components touch a socket. The parser consumes buffers |
| 93 | +you fill; the serializer produces buffers you drain. This means the |
| 94 | +same code works with any transport — Asio, io_uring, or a test harness |
| 95 | +that feeds canned data — without recompilation or abstraction layers. |
| 96 | + |
| 97 | +== Pages in This Section |
| 98 | + |
| 99 | +* xref:3a.containers.adoc[Containers] — build and inspect requests, |
| 100 | + responses, and header field collections |
| 101 | +* xref:3b.serializing.adoc[Serializing] — transform messages and body |
| 102 | + data into bytes for the wire |
| 103 | +* xref:3c.parsing.adoc[Parsing] — transform bytes from the wire into |
| 104 | + messages and body data |
0 commit comments