| Home | API Documentation |
Internal: Mug · ThorsMug · ThorsSlack · NisseServer · NisseHTTP · ThorsSocket · ThorsCrypto · ThorsSerializer · ThorsMongo · ThorsLogging · ThorsIOUtil
Detailed implementation of HTTP parsing, response generation, URL routing, and stream handling in the NisseHTTP library.
Source: third/Nisse/src/NisseHTTP/
NisseHTTP builds on NisseServer to provide HTTP/1.x support:
┌──────────────────────────────────────────────────┐
│ User Application │
├──────────────────────────────────────────────────┤
│ NisseHTTP │
│ PyntHTTP · HTTPHandler · Request · Response │
│ URL · Headers · PathMatcher · Streams │
├──────────────────────────────────────────────────┤
│ NisseServer │
└──────────────────────────────────────────────────┘
PyntHTTP is an HTTP-specific Pynt implementation. Its handleRequest() method:
Request by parsing the stream.PyntResult::Done.Response (default 200) and calls the pure virtual processRequest().PyntResult::More (HTTP keep-alive).Files: Request.h, Request.cpp
Parsing happens during Request construction:
HeaderRequest (multi-value map).Host header with request path.Content-Length or Transfer-Encoding: chunked, create the appropriate StreamInput.If any parsing step fails, failResponse is populated and isValidRequest() returns false.
RequestVariables is populated by HTTPHandler with:
content-type: application/x-www-form-urlencoded)All are accessed via req.variables()["key"] which returns an empty string on miss.
Files: Response.h, Response.cpp
The status line and headers are not sent until needed:
addHeaders() sends the status line and headers.body() sends the status line and encoding header.body(BodyEncoding) accepts a variant:
std::size_t or std::streamsize – fixed content-lengthEncoding::Chunked – chunked transfer encodingThe returned std::ostream& uses a StreamBufOutput that handles the encoding transparently.
If neither addHeaders() nor body() was called, the destructor sends content-length: 0. The destructor also logs the response time.
Files: URL.h, URL.cpp
Parses a URL into components:
http://localhost:53/status?name=ryan#234
│ │ │ │ │
protocol origin path query hash
│
host (hostname:port)
Supports copy, move, swap, and equality comparison. The param(name) method parses the query string to find parameter values.
Files: HeaderRequest.h, HeaderRequest.cpp
Stores incoming headers as std::map<std::string, std::vector<std::string>>. Supports multiple values per header name (required for headers like Set-Cookie).
Files: HeaderResponse.h, HeaderResponse.cpp
Stores outgoing headers as std::map<std::string, std::string>. Single value per header.
Files: HeaderPassThrough.h, HeaderPassThrough.cpp
Used in reverse-proxy scenarios. Reads headers from an upstream response and writes them directly to the downstream response without full parsing. Detects Content-Length and Transfer-Encoding to determine body encoding.
Files: StreamInput.h, StreamInput.cpp
Custom std::streambuf for reading request bodies. Supports:
preloadStreamIntoBuffer(): reads the entire body into memory and returns a std::string_view.Files: StreamOutput.h, StreamOutput.cpp
Custom std::streambuf for writing response bodies. Supports:
0\r\n\r\n) on destruction.Files: PathMatcher.h, PathMatcher.cpp
Each registered path is decomposed into:
matchSections – literal string segments between capturesnames – names of capture groupsmethod – method filter (Method or All)action – function pointer + dataFor a given URL path:
matchSections, extracting characters between literal segments as capture values.Actions are stored as a structured type (rather than std::function directly) to avoid issues with dlclose() on dynamically loaded plugins.
Files: ClientStream.h, ClientStream.cpp
Opens a TLS socket connection to a URL. Parses host and port from the URL, establishes an SSL connection.
Files: ClientRequest.h, ClientRequest.cpp
Builds and sends an HTTP request. The first line and Host header are sent lazily. The destructor calls flushRequest().
Files: ClientResponse.h, ClientResponse.cpp
Reads and parses an HTTP response (status line and headers).
File: Util.h, Util.cpp
Pairs an integer code with its standard message text.
Singleton lookup table for standard HTTP status codes (200, 201, 301, 400, 404, 500, etc.).
A std::map<std::string, std::string> wrapper with:
exists(key) – check if key is presentoperator[](key) – returns empty string on missinsert_or_assign(key, value) – insert or updateusing Header = std::variant<HeaderResponse const&, HeaderPassThrough const&>;
Allows response.addHeaders() to accept either header type.
using BodyEncoding = std::variant<std::size_t, std::streamsize, Encoding>;
When HTTPHandler::processRequest() is called:
PathMatcher::findMatch().request.variables() with: HTTP headers, URL query parameters, path-captured variables, and form body variables.
b. Call the validation function; send 400 on failure.
c. Call the user action.| File | Description |
|---|---|
PyntHTTP.h/.cpp |
HTTP implementation of Pynt |
PyntHTTPControl.h/.cpp |
HTTP control endpoint |
HTTPHandler.h/.cpp |
URL-pattern-based route dispatcher |
Request.h/.cpp |
HTTP request parser |
Response.h/.cpp |
HTTP response builder |
URL.h/.cpp |
URL parser |
HeaderRequest.h/.cpp |
Incoming header container |
HeaderResponse.h/.cpp |
Outgoing header container |
HeaderPassThrough.h/.cpp |
Proxy-style header forwarding |
HeaderStreamOperator.tpp |
Variant stream operator for Header type |
StreamInput.h/.cpp |
Input streambuf (content-length / chunked) |
StreamOutput.h/.cpp |
Output streambuf (content-length / chunked) |
PathMatcher.h/.cpp |
URL pattern matching with captures |
Util.h/.cpp |
Enums, StatusCode, RequestVariables |
ClientStream.h/.cpp |
Outbound TLS connection |
ClientRequest.h/.cpp |
Outbound HTTP request builder |
ClientResponse.h/.cpp |
Inbound HTTP response parser |