-
Notifications
You must be signed in to change notification settings - Fork 0
Requests
ML::Requests is the HTTP client. The modern API returns a rich ML::Response;
older string-returning methods are kept for backwards compatibility.
struct Response {
long status; // HTTP status code (0 if the request failed to send)
std::string body; // response body
std::map<std::string, std::string> headers; // response headers, keys lowercased
bool ok() const; // true for any 2xx status
};Each verb returns a full Response. headers is a list of complete header lines.
timeoutSeconds defaults to 0 (wait indefinitely); set it to abort slow requests.
Response get (std::string url, std::vector<std::string> headers = {}, long timeoutSeconds = 0);
Response post (std::string url, std::string body, std::vector<std::string> headers = {}, long timeoutSeconds = 0);
Response put (std::string url, std::string body, std::vector<std::string> headers = {}, long timeoutSeconds = 0);
Response patch(std::string url, std::string body, std::vector<std::string> headers = {}, long timeoutSeconds = 0);
Response del (std::string url, std::vector<std::string> headers = {}, long timeoutSeconds = 0);
Response head (std::string url, std::vector<std::string> headers = {}, long timeoutSeconds = 0);Requests req;
Response r = req.get("https://catfact.ninja/fact");
if (r.ok()) std::cout << r.body;
Response p = req.post("https://httpbin.org/post",
R"({"name":"widget"})",
{ "Content-Type: application/json" },
10); // 10s timeout
std::cout << p.status << " " << p.headers["content-type"];ML::Auth builds Authorization header lines.
Auth::bearer(token) // "Authorization: Bearer <token>"
Auth::basic(user, password) // "Authorization: Basic <base64(user:password)>"
Auth::apiKey("x-api-key", key) // "x-api-key: <key>"
req.get(url, { Auth::bearer(token) });ML::Url builds query strings with proper percent-encoding.
Url::encode("hello world"); // "hello%20world"
Url::build("https://api/search", {{"q","a b"},{"n","2"}}); // "https://api/search?n=2&q=a%20b"Streams the response body straight to disk (memory-light for large files). The
optional progress callback receives (bytesNow, bytesTotal). Returns true on a
2xx response.
req.download("https://example.com/big.zip", "C:/downloads/big.zip");
req.download(url, path, [](long now, long total) {
std::cout << now << " / " << total << "\r";
});upload sends multipart/form-data (file uploads, etc.). Each FormPart is a
text field, or a file when isFile is true (put the file path in content).
struct FormPart { std::string name; std::string content; bool isFile = false; };
Response r = req.upload("https://api.example.com/images",
{ {"file", "C:/photo.jpg", true}, // a file part
{"title", "vacation", false} }); // a text fieldOpt-in automatic retry for the verb methods. Retries on 429 and 5xx, honoring
the server's Retry-After header when present, otherwise using exponential
backoff (baseMs, 2*baseMs, 4*baseMs, ...). Off by default.
req.setRetries(3); // retry up to 3 times
req.setRetryBackoff(1000); // base delay 1000 ms
Response r = req.get(url); // transparently retries on 429/5xxThese return just the response body as a string and remain for compatibility:
pingDomain, getReq, postReq, putReq, headReq, deleteReq (several with a
single-header overload). New code should prefer the verb methods above.