docs(http1): document the HTTP/1.1 stack, and expose the client's timeout
README: HTTP/1.1 in the intro, feature list, module list, browser-build exclusions, dependencies and test list, plus a Components section covering both classes, the standalone codec, what is and is not implemented, the smuggling-shaped inputs that are rejected, and an explicit note that this path is plaintext and belongs behind a TLS terminator. ClientHTTP1::timeout was hard-coded and invisible; make it a public member alongside `limits`, mirroring the listener's timeouts. Also pipelining coverage in ShouldSendRecieveHTTP1: two requests written before either is answered, driven from a raw socket since ClientHTTP1 waits for each response. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ea1310faec
commit
a79ab6a024
4 changed files with 102 additions and 8 deletions
|
|
@ -73,6 +73,34 @@ int main() {
|
|||
// Every exchange above shared one connection.
|
||||
Check(listener.listener.AcceptedCount() == 1, "the whole test used a single connection");
|
||||
|
||||
// Pipelining: two requests written in one go, before either is
|
||||
// answered. The responses must come back in order, on that same
|
||||
// connection. ClientHTTP1 never does this — it waits for each
|
||||
// response — so drive it from a raw socket.
|
||||
{
|
||||
ClientTCP socket("localhost", 8090);
|
||||
const std::string pipelined =
|
||||
"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"
|
||||
"GET /nope HTTP/1.1\r\nHost: localhost\r\n\r\n";
|
||||
socket.Send(pipelined.data(), static_cast<std::uint32_t>(pipelined.size()));
|
||||
|
||||
HTTP1::MessageParser parser(HTTP1::MessageKind::Response);
|
||||
std::string first;
|
||||
std::string second;
|
||||
while (second.empty()) {
|
||||
std::vector<char> chunk = socket.RecieveSync();
|
||||
parser.Feed(chunk.data(), chunk.size());
|
||||
while (parser.Complete()) {
|
||||
HTTPResponse response = parser.TakeResponse();
|
||||
(first.empty() ? first : second) = response.status;
|
||||
parser.Reset();
|
||||
if (!second.empty()) break;
|
||||
}
|
||||
}
|
||||
Check(first == "200", "first pipelined response");
|
||||
Check(second == "404", "second pipelined response, in order");
|
||||
}
|
||||
|
||||
listener.Stop();
|
||||
} catch (const std::exception& error) {
|
||||
std::println("threw: {}", error.what());
|
||||
|
|
|
|||
Loading…
Reference in a new issue