{"id":34896696,"url":"https://github.com/uctakeoff/uc-curl","last_synced_at":"2026-04-28T03:35:02.265Z","repository":{"id":16309199,"uuid":"79696823","full_name":"uctakeoff/uc-curl","owner":"uctakeoff","description":"uc::curl is a libcurl wrapper library created C++11 single-header.","archived":false,"fork":false,"pushed_at":"2022-01-28T13:19:36.000Z","size":56,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2023-09-04T06:31:17.278Z","etag":null,"topics":["http","http-client","libcurl","wrapper"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uctakeoff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-22T05:49:57.000Z","updated_at":"2023-05-03T14:36:13.000Z","dependencies_parsed_at":"2022-08-07T08:15:19.164Z","dependency_job_id":null,"html_url":"https://github.com/uctakeoff/uc-curl","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/uctakeoff/uc-curl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uctakeoff%2Fuc-curl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uctakeoff%2Fuc-curl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uctakeoff%2Fuc-curl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uctakeoff%2Fuc-curl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uctakeoff","download_url":"https://codeload.github.com/uctakeoff/uc-curl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uctakeoff%2Fuc-curl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32365510,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-27T20:07:02.737Z","status":"online","status_checked_at":"2026-04-28T02:00:07.250Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http","http-client","libcurl","wrapper"],"created_at":"2025-12-26T07:06:25.576Z","updated_at":"2026-04-28T03:35:02.254Z","avatar_url":"https://github.com/uctakeoff.png","language":"C++","readme":"# uc::curl\r\n\r\nuc::curl is a libcurl wrapper library created C++11 single-header.\r\nIt depends only on libcurl and STL.\r\n\r\n```cpp:sample.cpp\r\n#include \u003ciostream\u003e\r\n#include \u003cstring\u003e\r\n#include \"uccurl.h\"\r\n\r\nint main()\r\n{\r\n    try {\r\n        uc::curl::global libcurlInit;\r\n\r\n        std::string data;\r\n        uc::curl::easy(\"http://www.example.com/\") \u003e\u003e data;\r\n\r\n    } catch (std::exception\u0026 ex) {\r\n        std::cerr \u003c\u003c \"exception : \" \u003c\u003c ex.what() \u003c\u003c std::endl;\r\n        return 1;\r\n    }\r\n    return 0;\r\n}\r\n\r\n```\r\n\r\nbuild\r\n```bash\r\n$ g++ sample.cpp -std=c++11 -lcurl\r\n```\r\n\r\n## License\r\n\r\nMIT-Lisence\r\n\r\n## EASY interface\r\n\r\n### Simple to use.\r\n\r\n[sample.c](https://curl.haxx.se/libcurl/c/simple.html) above is roughly rewritten as follows.\r\n\r\n```cpp\r\n// See https://curl.haxx.se/libcurl/c/simple.html\r\n#include \u003ciostream\u003e\r\n#include \"uccurl.h\"\r\n\r\nint main()\r\n{\r\n    try {\r\n        uc::curl::easy(\"http://example.com\").perform();\r\n    } catch (std::exception\u0026 ex) {\r\n        std::cerr \u003c\u003c \"exception : \" \u003c\u003c ex.what() \u003c\u003c std::endl;\r\n        return 1;\r\n    }\r\n    return 0;\r\n}\r\n```\r\n\r\n\r\n`uc::curl::easy(\"http://example.com\")` has the same effect as:\r\n\r\n```c\r\nCURL* curl = curl_easy_init();\r\ncurl_easy_setopt(curl, CURLOPT_URL, \"http://example.com\");\r\ncurl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);\r\ncurl_easy_setopt(curl, CURLOPT_MAXREDIRS, 20L);\r\n```\r\n\r\nThe value of [`CURLOPT_MAXREDIRS`](https://curl.haxx.se/libcurl/c/CURLOPT_MAXREDIRS.html) can be specified as the second argument. The default value is 20.\r\n\r\n* `uc::curl::easy(\"http://example.com\", 0)` will make libcurl refuse any redirect.\r\n* `uc::curl::easy(\"http://example.com\", -1)`  for an infinite number of redirects.\r\n\r\n### setopt\r\n\r\nThere are several ways.\r\n\r\n```cpp\r\n    uc::curl::easy curl;\r\n    curl.setopt(CURLOPT_VERBOSE, 1L);       // OK: Compatible with conventional\r\n    curl.setopt\u003cCURLOPT_VERBOSE\u003e(1L);       // OK: argument type check\r\n    curl.setopt\u003cCURLOPT_VERBOSE\u003e();         // OK: If no argument is specified, 1L is specified.\r\n//  curl.setopt\u003cCURLOPT_VERBOSE\u003e(\"text\");   // Complie error\r\n\r\n    std::string url(\"http://example.com\");\r\n    curl.uri(url);                          // Dedicated function\r\n    curl.setopt(CURLOPT_URL, url.c_str());\r\n    curl.setopt\u003cCURLOPT_URL\u003e(url);\r\n```\r\n\r\n### getinfo\r\n\r\nAutomatically resolve type.\r\n```cpp\r\n    const char* url = curl.uri();  // getinfo\u003cCURLINFO_EFFECTIVE_URL\u003e();\r\n\r\n    const char* type = curl.getinfo\u003cCURLINFO_CONTENT_TYPE\u003e();\r\n    long code = curl.getinfo\u003cCURLINFO_RESPONSE_CODE\u003e();\r\n    double time = curl.getinfo\u003cCURLINFO_TOTAL_TIME\u003e();\r\n    curl_certinfo* info = curl.getinfo\u003cCURLINFO_CERTINFO\u003e();\r\n    uc::curl::slist list = curl.getinfo\u003cCURLINFO_COOKIELIST\u003e();\r\n```\r\n\r\n### GET method\r\n\r\nYou can use `std::string`, `std::ostream`, `size_t(const char*, size_t)`  for the `operator\u003e\u003e()`.\r\n\r\n```cpp\r\n    uc::curl::easy curl(\"http://example.com\");\r\n\r\n    // output to cerr\r\n    curl \u003e\u003e std::cerr;\r\n\r\n    // output file\r\n    curl \u003e\u003e std::ofstream(\"page.out\", std::ios::out | std::ios::binary);\r\n\r\n    // get in memory\r\n    std::string response;\r\n    curl \u003e\u003e response;\r\n\r\n    // callback function\r\n    curl \u003e\u003e [](const char* ptr, size_t size) {\r\n            std::cout \u003c\u003c \"## receive : \" \u003c\u003c size \u003c\u003c \"bytes\\n\"\r\n                \u003c\u003c std::string(ptr, size) \u003c\u003c \"\\n\\n\";\r\n            return size;\r\n        };\r\n```\r\n\r\n`operator\u003e\u003e()` performs the following processing in order.\r\n\r\n1. Set [`CURLOPT_WRITEDATA`](https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html) and [`CURLOPT_WRITEFUNCTION`](https://curl.haxx.se/libcurl/c/CURLOPT_WRITEDATA.html).\r\n1. Call `uc::curl::easy::perform()`.\r\n1. Clear  [`CURLOPT_WRITEDATA`](https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html) and [`CURLOPT_WRITEFUNCTION`](https://curl.haxx.se/libcurl/c/CURLOPT_WRITEDATA.html).\r\n\r\n\r\n### POST method\r\n\r\n[simplepost.c](https://curl.haxx.se/libcurl/c/simplepost.html) above is roughly rewritten as follows.\r\n\r\n```cpp\r\n    // POST string\r\n    uc::curl::easy(url).postfields(\"moo mooo moo moo\").perform();\r\n```\r\n\r\n`postfields()` can take `std::string`, `std::istream`, `uc::curl::form` as arguments.\r\n\r\n```cpp\r\n    // POST file\r\n    std::ifstream is(\"formdata.txt\", std::ios::in | std::ios::binary);\r\n    uc::curl::easy(url).postfields(is).perform();\r\n```\r\n\r\n```cpp\r\n    // POST form data\r\n    uc::curl::form formpost;\r\n    formpost\r\n        .file(\"sendfile\", \"postit2.c\")\r\n        .contents(\"filename\", \"postit2.c\")\r\n        .contents(\"submit\", \"send\");    \r\n    uc::curl::easy(url).postfields(formpost).perform();\r\n```\r\n\r\n`uc::curl::form` is a `struct curl_httppost` wrapper using `std::unique_ptr`.\r\n\r\n### PUT method\r\n\r\n```cpp\r\n    std::ifstream is(filename, std::ios::in | std::ios::binary);\r\n    uc::curl::easy(uri).setopt\u003cCURLOPT_UPLOAD\u003e().body(is).perform();\r\n```\r\n\r\n### HEAD method\r\n\r\n```cpp\r\n    // You can use `std::string`, `std::ostream`, `size_t(const char*, size_t)`  for the `response_header()`.\r\n    auto resheader = [](const char* ptr, size_t size) {\r\n        std::cout \u003c\u003c \"###\" \u003c\u003c std::string(ptr, size);\r\n        return size;\r\n    };\r\n    uc::curl::easy(url).setopt\u003cCURLOPT_NOBODY\u003e().response_header(resheader).perform();\r\n```\r\n\r\n### DELETE method\r\n\r\n```cpp\r\n    uc::curl::easy(url).setopt\u003cCURLOPT_CUSTOMREQUEST\u003e(\"DELETE\").perform();\r\n```\r\n\r\n### uc::curl::slist\r\n\r\n`uc::curl::slist` is a `struct curl_slist` wrapper using `std::unique_ptr`. \r\n\r\n\r\nset sample\r\n```cpp\r\n    auto chunk = uc::curl::create_slist(\r\n        \"Accept:\", \r\n        \"Another: yes\", \r\n        \"Host: example.com\", \r\n        \"X-silly-header;\"); \r\n    uc::curl::easy(url).header(chunk).perform();\r\n```\r\n\r\nget sample\r\n```cpp\r\n    uc::curl::slist list = curl.getinfo\u003cCURLINFO_COOKIELIST\u003e();\r\n\r\n    // e : const char*\r\n    for (auto\u0026\u0026 e : list) {\r\n        std::cout \u003c\u003c e \u003c\u003c \"\\n\";\r\n    }\r\n```\r\n\r\n## MULTI interface\r\n\r\n### Simple to use.\r\n\r\n[multi-single.c](https://curl.haxx.se/libcurl/c/multi-single.html) above is roughly rewritten as follows.\r\n\r\n```cpp\r\n#include \u003ciostream\u003e\r\n#include \u003cstdexcept\u003e\r\n#include \u003cchrono\u003e\r\n#include \"uccurl.h\"\r\n\r\nint main()\r\n{\r\n    try {\r\n        uc::curl::global libcurlInit;\r\n\r\n        uc::curl::easy http_handle(\"http://www.example.com/\");\r\n\r\n        uc::curl::multi multi_handle;\r\n        multi_handle.add(http_handle);\r\n\r\n        while (multi_handle.perform() \u003e 0) {\r\n            multi_handle.poll(std::chrono::seconds{1});\r\n        }\r\n\r\n        multi_handle.remove(http_handle);\r\n    } catch (std::exception\u0026 ex) {\r\n        std::cerr \u003c\u003c \"exception : \" \u003c\u003c ex.what() \u003c\u003c std::endl;\r\n        return 1;\r\n    }\r\n    return 0;\r\n}\r\n```\r\n\r\n\r\n### `curl_multi_info_read()` API\r\n\r\nInstead of `curl_multi_info_read()`, there are `for_each_done_info()`.\r\n\r\nbefore\r\n```cpp\r\nwhile ((msg = curl_multi_info_read(multi_handle, \u0026msgs_left))) {\r\n    if (msg-\u003emsg == CURLMSG_DONE) {\r\n        char *url;\r\n        curl_easy_getinfo(msg-\u003eeasy_handle, CURLINFO_EFFECTIVE_URL, \u0026url);\r\n        printf(\"%d : %s\\n\", msg-\u003edata.result, url);\r\n    }\r\n}\r\n```\r\nafter\r\n```\r\nmulti_handle.for_each_done_info([](uc::curl::easy_ref\u0026\u0026 h, CURLcode result) {\r\n    std::cout \u003c\u003c result \u003c\u003c  \" : \" \u003c\u003c h.uri() \u003c\u003c \"\\n\";\r\n});\r\n```\r\n\r\n\r\n\r\n\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuctakeoff%2Fuc-curl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuctakeoff%2Fuc-curl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuctakeoff%2Fuc-curl/lists"}