Implementation:ClickHouse ClickHouse Poco HTTPResponse Impl
base/poco/Net/src/HTTPResponse.cpp:1-407
ClickHouse_ClickHouse
ClickHouse_ClickHouse_HTTP_Client_Communication
This page documents the implementation details of the `HTTPResponse` class. The corresponding header is already documented under the ClickHouse_ClickHouse_HTTP_Client_Communication principle.
Purpose
Implements the `Poco::Net::HTTPResponse` class, which represents an HTTP response message. This file provides the logic for constructing responses with status codes and reason phrases, serializing responses to output streams, parsing responses from input streams, managing cookies and dates, and mapping HTTP status codes to their standard reason strings.
Code Reference
Status-to-Reason Mapping
The file defines a comprehensive set of `const std::string` reason phrases covering HTTP status codes from 1xx through 5xx. The `getReasonForStatus` method maps a numeric status code to its human-readable reason via a switch statement:
const std::string& HTTPResponse::getReasonForStatus(HTTPStatus status)
{
switch (status)
{
case HTTP_CONTINUE:
return HTTP_REASON_CONTINUE;
case HTTP_OK:
return HTTP_REASON_OK;
// ... covers ~60 standard HTTP status codes
default:
return HTTP_REASON_UNKNOWN;
}
}
Response Serialization (write / beginWrite)
void HTTPResponse::beginWrite(std::ostream& ostr) const
{
ostr << getVersion() << " " << static_cast<int>(_status) << " " << _reason << "\r\n";
HTTPMessage::write(ostr);
}
void HTTPResponse::write(std::ostream& ostr) const
{
beginWrite(ostr);
ostr << "\r\n";
}
Response Parsing (read)
Parses the status line character by character from an `std::istream`, extracting version, status code, and reason phrase with length limits (`MAX_VERSION_LENGTH`, `MAX_STATUS_LENGTH`, `MAX_REASON_LENGTH`). Delegates header parsing to `HTTPMessage::read`:
void HTTPResponse::read(std::istream& istr)
{
// Character-by-character parsing of: "HTTP/1.1 200 OK\r\n"
// Followed by HTTPMessage::read(istr) for headers
// Followed by consuming the blank line separator
}
Cookie Management
void HTTPResponse::addCookie(const HTTPCookie& cookie)
{
add(SET_COOKIE, cookie.toString());
}
void HTTPResponse::getCookies(std::vector<HTTPCookie>& cookies) const
{
cookies.clear();
NameValueCollection::ConstIterator it = find(SET_COOKIE);
while (it != end() && Poco::icompare(it->first, SET_COOKIE) == 0)
{
NameValueCollection nvc;
splitParameters(it->second.begin(), it->second.end(), nvc);
cookies.push_back(HTTPCookie(nvc));
++it;
}
}
I/O Contract
| Input | Output | Side Effects |
|---|---|---|
| `HTTPStatus` enum value | `HTTPResponse` object with status and reason | None |
| `std::ostream&` via `write` | Serialized HTTP response status line + headers + CRLF | Writes to output stream |
| `std::istream&` via `read` | Populated `HTTPResponse` with version, status, reason, headers | Reads from input stream; throws `MessageException` or `NetException` on malformed input |
| `HTTPCookie` via `addCookie` | None | Adds `Set-Cookie` header to response |
| `Poco::Timestamp` via `setDate` | None | Sets `Date` header in HTTP date format |
Usage Examples
// Constructing and serializing a response
Poco::Net::HTTPResponse response(Poco::Net::HTTPResponse::HTTP_OK);
response.setDate(Poco::Timestamp());
response.addCookie(Poco::Net::HTTPCookie("session", "abc123"));
response.write(outputStream);
// Parsing a response from a stream
Poco::Net::HTTPResponse response;
response.read(inputStream);
int status = response.getStatus(); // e.g., 200
std::string reason = response.getReason(); // e.g., "OK"
std::vector<Poco::Net::HTTPCookie> cookies;
response.getCookies(cookies);
Internal Details
- The `read` method enforces maximum lengths on version (8 chars), status (3 chars), and reason strings to guard against malformed or malicious responses.
- The `setStatus(const std::string&)` overload parses a string status code to an integer using `NumberParser::parse`.
- The `getHeaders` method copies all headers into an `std::map`, flattening the `NameValueCollection` representation.
- All reason string constants are defined as file-scope `const std::string` instances, avoiding repeated allocations.
- The `beginWrite` method allows partial writing (status line + headers without the terminating blank line), used by subclasses such as `HTTPServerResponse`.