Skip to content

feat: add public Client core execution path - #15

Merged
zuudevs merged 6 commits into
mainfrom
feat/client-core
Sep 14, 2026
Merged

zuudevs merged 6 commits into
mainfrom
feat/client-core

Conversation

@zuudevs

@zuudevs zuudevs commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Summary

Adds the first public end-to-end HTTP execution path through Client, connecting the already-merged URL, HTTP serialization/parsing, resolver, and TCP transport layers.

Public API

  • include/cpp_request/client.hpp
    • stateful Client
    • request(const Request&)
    • member helpers for GET, HEAD, POST, PUT, PATCH, DELETE
    • configurable connect/read/write timeouts
    • one-shot free helpers for the same methods
    • default timeouts: 5s connect, 30s read, 30s write

Execution pipeline

Client::request() now performs:

  1. request serialization and URL validation
  2. OS-backed endpoint resolution
  3. timed TCP connection establishment
  4. request-head transmission
  5. zero-copy request-body transmission
  6. incremental socket reads
  7. incremental HTTP/1.1 response parsing
  8. completed owning Response return

Timeout semantics

  • connect timeout bounds TCP connection establishment
  • write timeout is one shared budget for the complete request transmission (head + body)
  • read timeout applies to each read_some() operation, matching the transport contract

EOF/error behavior

  • transport ConnectionClosed is treated as HTTP EOF and passed to ResponseParser::finish_eof()
  • valid close-delimited responses therefore complete successfully
  • premature closure of Content-Length/chunked responses maps to parser UnexpectedEof
  • other transport, URL, DNS, timeout, and protocol errors propagate through Result<Response>

Tests

Adds local loopback end-to-end coverage for:

  • custom-header GET request and Content-Length response
  • POST body transmission and automatic Content-Length
  • chunked response decoding through the full Client path
  • close-delimited response completion on peer close
  • malformed response propagation
  • unsupported HTTPS rejection before networking

All integration tests use local ephemeral loopback sockets only.

Scope

This PR intentionally opens a fresh TCP connection for every request. It does not implement persistent connection reuse or redirect handling yet. Those remain isolated follow-up changes so the basic execution pipeline can stabilize first.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5a55c5621

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/client.cpp
Comment on lines +93 to +94
if (read_result.error().code == ErrorCode::ConnectionClosed) {
auto eof_result = parser.finish_eof();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate connection resets instead of treating them as EOF

When a close-delimited response is interrupted by ECONNRESET/WSAECONNRESET, TcpConnection::read_some() reports ConnectionClosed with a nonzero native error, so this branch calls finish_eof() and returns the partially received body as a successful response. Only an orderly recv() == 0 closure is valid EOF; reset-style closures must remain errors to avoid silently accepting truncated response data.

Useful? React with 👍 / 👎.

@zuudevs
zuudevs merged commit daceaba into main Sep 14, 2026
6 checks passed
@zuudevs
zuudevs deleted the feat/client-core branch September 14, 2026 23:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant