Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Aug 19, 2025

This PR implements the feature request from Issue #2210, adding support for Client POST requests with raw binary data (const char *body, size_t content_length) and ContentReceiver for streaming responses.

Problem

The existing httplib library supported ContentReceiver (for streaming responses) with POST requests, but only for std::string body data. There was no way to send raw binary data with a specific length while also receiving streaming responses. This limitation prevented use cases like:

  • LLM REST servers that accept binary payloads and stream token responses
  • Server-Sent Events (SSE) from POST endpoints with binary data
  • Consistent API usage between string and binary data for streaming responses

Solution

Added 4 new POST method overloads to both Client and ClientImpl classes:

// Without custom headers
Result Post(const std::string &path, const char *body, size_t content_length, 
           const std::string &content_type, ContentReceiver content_receiver, 
           DownloadProgress progress = nullptr);

// With custom headers  
Result Post(const std::string &path, const Headers &headers, const char *body, 
           size_t content_length, const std::string &content_type, 
           ContentReceiver content_receiver, DownloadProgress progress = nullptr);

Implementation Details

  • ClientImpl methods: Create Request objects and use req.body.assign(body, content_length) to properly handle binary data including null bytes
  • Client methods: Delegate to corresponding ClientImpl methods following established patterns
  • Consistent API: Uses the same ContentReceiver pattern as existing string-based methods
  • Binary data support: Correctly handles data containing null bytes via explicit length parameter

Example Usage

httplib::Client cli("llm-server.com", 8080);
const char* binary_payload = "..."; // Binary data
size_t payload_size = 1024;

// Stream response while sending binary data
auto res = cli.Post("/v1/chat/completions", binary_payload, payload_size, 
                   "application/octet-stream",
                   [](const char* data, size_t len) {
                       std::cout << std::string(data, len); // Stream tokens
                       return true;
                   });

Testing

Added comprehensive test cases covering:

  • POST with raw binary data and ContentReceiver
  • POST with custom headers, raw binary data and ContentReceiver
  • Binary data containing null bytes
  • Verification that existing methods remain functional

Backward Compatibility

This change is fully backward compatible - no existing API signatures were modified, only new overloads were added.

Fixes #2210

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • httpbin.org
    • Triggering command: ./test_issue_2210 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@yhirose yhirose changed the title [WIP] Issue #2210の提案を調べて [WIP] Investigate the suggestion in #2210 Aug 19, 2025
@yhirose yhirose marked this pull request as ready for review August 19, 2025 19:16
@yhirose yhirose closed this Aug 19, 2025
@Copilot Copilot AI changed the title [WIP] Investigate the suggestion in #2210 Add POST methods with raw binary data and ContentReceiver support for streaming responses Aug 19, 2025
@Copilot Copilot AI requested a review from yhirose August 19, 2025 19:32
Copilot finished work on behalf of yhirose August 19, 2025 19:32
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.

Client Post with SSE
2 participants