├── README.md ├── example.cpp ├── LICENSE └── curl4.hpp /README.md: -------------------------------------------------------------------------------- 1 | # curl4cpp 2 | ## single header cURL wrapper for C++ around libcURL. 3 | 4 | ### An example: 5 | ```cpp 6 | #include 7 | #include 8 | #include "curl4.hpp" 9 | 10 | int main() { 11 | curl4::CURL4 init = curl4::easy::init(); 12 | 13 | { 14 | std::string val; 15 | 16 | init.setopt(CURLOPT_URL, "https://raw.githubusercontent.com/ferhatgec/bufsize/master/example.cpp"); 17 | init.setopt(CURLOPT_WRITEFUNCTION, curl4::easy::writefunc); 18 | init.setopt(CURLOPT_WRITEDATA, &val); 19 | 20 | CURLcode res = curl4::easy::perform(init); 21 | 22 | std::cout << val << '\n'; 23 | } 24 | 25 | return 0; 26 | } 27 | ``` 28 | 29 | ### curl4cpp licensed under the terms of MIT License. 30 | -------------------------------------------------------------------------------- /example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "curl4.hpp" 4 | 5 | // raw c code taken from 6 | // https://stackoverflow.com/questions/2329571/c-libcurl-get-output-into-a-string 7 | 8 | int main() { 9 | curl4::CURL4 init = curl4::easy::init(); 10 | 11 | std::string url = "https://raw.githubusercontent.com/ferhatgec/bufsize/master/example.cpp"; 12 | 13 | { 14 | std::string val; 15 | 16 | init.setopt(CURLOPT_URL, url); 17 | init.setopt(CURLOPT_WRITEFUNCTION, curl4::easy::writefunc); 18 | init.setopt(CURLOPT_WRITEDATA, &val); 19 | 20 | // curl4::easy::setopt(init, CURLOPT_URL, "https://raw.githubusercontent.com/ferhatgec/bufsize/master/example.cpp"); 21 | // curl4::easy::setopt(init, CURLOPT_WRITEFUNCTION, writefunc); 22 | // curl4::easy::setopt(init, CURLOPT_WRITEDATA, &val); 23 | 24 | CURLcode res = curl4::easy::perform(init); 25 | 26 | std::cout << val << '\n'; 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2022 Ferhat Geçdoğan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /curl4.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2021-2022 Ferhat Geçdoğan All Rights Reserved. 4 | // Distributed under the terms of the MIT License. 5 | // 6 | // curl4cpp - work-in-progress single header libcURL wrapper 7 | // 8 | // there's so much structs are not wrapped yet 9 | // those are starts with '__' 10 | // 11 | // github.com/ferhatgec/curl4cpp 12 | 13 | #ifndef CURL4CPP_CURL4_HPP 14 | #define CURL4CPP_CURL4_HPP 15 | 16 | #include 17 | #include 18 | 19 | #define CURL4CPP_ENABLE_CTIME 20 | 21 | #ifdef CURL4CPP_ENABLE_CTIME 22 | #include 23 | #endif // CURL4CPP_ENABLE_CTIME 24 | 25 | using __curl_easyoption = struct curl_easyoption; 26 | using __curl_easytype = curl_easytype; 27 | using __curl_httppost = struct curl_httppost; 28 | using __curl_formget_callback = curl_formget_callback; 29 | using __curl_mime = curl_mime; 30 | using __curl_mimepart = curl_mimepart; 31 | using __curl_off_t = curl_off_t; 32 | 33 | using __curl_read_callback = curl_read_callback; 34 | using __curl_seek_callback = curl_seek_callback; 35 | using __curl_free_callback = curl_free_callback; 36 | 37 | using __curl_s_list = struct curl_slist; 38 | 39 | using __curl_socket = curl_socket_t; 40 | 41 | using __fd_set = fd_set; 42 | using __curl_waitfd = struct curl_waitfd; 43 | 44 | namespace curl4 { 45 | class CURL4 { 46 | public: 47 | CURL* init; 48 | public: 49 | CURL4() = default; 50 | ~CURL4() { 51 | curl_easy_cleanup(this->init); 52 | } 53 | 54 | void cleanup() noexcept { 55 | curl_easy_cleanup(this->init); 56 | } 57 | 58 | CURL4 duphandle() noexcept { 59 | #if __cplusplus >= 202002L 60 | CURL4 init; 61 | init.init = curl_easy_duphandle(this->init); 62 | return init; 63 | #else 64 | return CURL4 { .init = curl_easy_duphandle(this->init) }; 65 | #endif 66 | } 67 | 68 | std::string escape(const std::string str, unsigned length) noexcept { 69 | return std::string(curl_easy_escape(this->init, str.c_str(), length)); 70 | } 71 | 72 | template 73 | CURLcode getinfo(CURLINFO info, Param... args) noexcept { 74 | return curl_easy_getinfo(this->init, info, (args, ...)); 75 | } 76 | 77 | CURL4 initialize() noexcept { 78 | #if __cplusplus >= 202002L 79 | CURL4 init; 80 | init.init = curl_easy_init(); 81 | return init; 82 | #else 83 | return CURL4 { .init = curl_easy_init() }; 84 | #endif 85 | } 86 | 87 | template 88 | CURLcode recv(Buffer* buffer, 89 | std::size_t buffer_length, 90 | std::size_t* n) noexcept { 91 | return curl_easy_recv(this->init, buffer, buffer_length, n); 92 | } 93 | 94 | void reset() noexcept { 95 | curl_easy_reset(this->init); 96 | } 97 | 98 | template 99 | CURLcode send(const Buffer* buffer, 100 | std::size_t buffer_length, 101 | std::size_t* n) noexcept { 102 | return curl_easy_send(this->init, buffer, buffer_length, n); 103 | } 104 | 105 | template 106 | CURLcode setopt(CURLoption option, Param parameter) noexcept { 107 | if constexpr (std::is_same_v || std::is_same_v>) { 108 | return curl_easy_setopt(this->init, option, parameter.c_str()); 109 | } else { return curl_easy_setopt(this->init, option, parameter); } 110 | } 111 | 112 | std::string unescape(std::string url, 113 | unsigned inlength, 114 | int* outlength) noexcept { 115 | return curl_easy_unescape(this->init, url.c_str(), inlength, outlength); 116 | } 117 | 118 | CURLcode upkeep() noexcept { 119 | return curl_easy_upkeep(this->init); 120 | } 121 | }; 122 | 123 | namespace easy { 124 | enum class Type { 125 | CURL4OT_LONG, 126 | CURL4OT_VALUES, 127 | CURL4OT_OFF, 128 | CURL4OT_OBJECT, 129 | CURL4OT_STRING, 130 | CURL4OT_SLIST, 131 | CURL4OT_CBPTR, 132 | CURL4OT_BLOB, 133 | CURL4OT_FUNCTION 134 | }; 135 | 136 | class Option { 137 | public: 138 | std::string name; 139 | CURLoption id; 140 | Type type; 141 | unsigned flags; 142 | public: 143 | Option() = default; 144 | ~Option()= default; 145 | }; 146 | 147 | namespace match { 148 | __curl_easytype from(curl4::easy::Type val) noexcept { 149 | switch(val) { 150 | case curl4::easy::Type::CURL4OT_LONG: { 151 | return CURLOT_LONG; 152 | } 153 | 154 | case curl4::easy::Type::CURL4OT_VALUES: { 155 | return CURLOT_VALUES; 156 | } 157 | 158 | case curl4::easy::Type::CURL4OT_OFF: { 159 | return CURLOT_OFF_T; 160 | } 161 | 162 | case curl4::easy::Type::CURL4OT_OBJECT: { 163 | return CURLOT_OBJECT; 164 | } 165 | 166 | case curl4::easy::Type::CURL4OT_STRING: { 167 | return CURLOT_STRING; 168 | } 169 | 170 | case curl4::easy::Type::CURL4OT_SLIST: { 171 | return CURLOT_SLIST; 172 | } 173 | 174 | case curl4::easy::Type::CURL4OT_CBPTR: { 175 | return CURLOT_CBPTR; 176 | } 177 | 178 | case curl4::easy::Type::CURL4OT_BLOB: { 179 | return CURLOT_BLOB; 180 | } 181 | 182 | case curl4::easy::Type::CURL4OT_FUNCTION: { 183 | return CURLOT_FUNCTION; 184 | } 185 | } return CURLOT_OFF_T; 186 | } 187 | 188 | Type to(__curl_easytype val) noexcept { 189 | switch(val) { 190 | case CURLOT_LONG: { 191 | return curl4::easy::Type::CURL4OT_LONG; 192 | } 193 | 194 | case CURLOT_VALUES: { 195 | return curl4::easy::Type::CURL4OT_VALUES; 196 | } 197 | 198 | case CURLOT_OFF_T: { 199 | return curl4::easy::Type::CURL4OT_OFF; 200 | } 201 | 202 | case CURLOT_OBJECT: { 203 | return curl4::easy::Type::CURL4OT_OBJECT; 204 | } 205 | 206 | case CURLOT_STRING: { 207 | return curl4::easy::Type::CURL4OT_STRING; 208 | } 209 | 210 | case CURLOT_SLIST: { 211 | return curl4::easy::Type::CURL4OT_SLIST; 212 | } 213 | 214 | case CURLOT_CBPTR: { 215 | return curl4::easy::Type::CURL4OT_CBPTR; 216 | } 217 | 218 | case CURLOT_BLOB: { 219 | return curl4::easy::Type::CURL4OT_BLOB; 220 | } 221 | 222 | case CURLOT_FUNCTION: { 223 | return curl4::easy::Type::CURL4OT_FUNCTION; 224 | } 225 | } return curl4::easy::Type::CURL4OT_OFF; 226 | } 227 | } 228 | 229 | void cleanup(CURL4& handle) noexcept { 230 | curl_easy_cleanup(handle.init); 231 | } 232 | 233 | CURL4 duphandle(CURL4& handle) noexcept { 234 | #if __cplusplus >= 202002L 235 | CURL4 init; 236 | init.init = curl_easy_duphandle(handle.init); 237 | return init; 238 | #else 239 | return CURL4 { .init = curl_easy_duphandle(handle.init) }; 240 | #endif 241 | } 242 | 243 | std::string escape(CURL4& handle, const std::string str, unsigned length) noexcept { 244 | return std::string(curl_easy_escape(handle.init, str.c_str(), length)); 245 | } 246 | 247 | template 248 | CURLcode getinfo(CURL4& handle, CURLINFO info, Param... args) noexcept { 249 | return curl_easy_getinfo(handle.init, info, (args, ...)); 250 | } 251 | 252 | CURL4 init() noexcept { 253 | #if __cplusplus >= 202002L 254 | CURL4 init; 255 | init.init = curl_easy_init(); 256 | return init; 257 | #else 258 | return CURL4 { .init = curl_easy_init() }; 259 | #endif 260 | } 261 | 262 | Option option_by_id(CURLoption id) noexcept { 263 | auto val = const_cast<__curl_easyoption*>(curl_easy_option_by_id(id)); 264 | 265 | #if __cplusplus >= 202002L 266 | Option init; 267 | init.name = std::string(val->name); 268 | init.id = val->id; 269 | init.type = match::to(val->type); 270 | init.flags= val->flags; 271 | return init; 272 | #else 273 | return Option { 274 | .name = std::string(val->name), 275 | .id = val->id, 276 | .type = match::to(val->type), 277 | .flags= val->flags 278 | }; 279 | #endif 280 | } 281 | 282 | Option option_by_name(const std::string name) noexcept { 283 | auto val = const_cast<__curl_easyoption*>(curl_easy_option_by_name(name.c_str())); 284 | 285 | #if __cplusplus >= 202002L 286 | Option init; 287 | init.name = std::string(val->name); 288 | init.id = val->id; 289 | init.type = match::to(val->type); 290 | init.flags= val->flags; 291 | return init; 292 | #else 293 | return Option { 294 | .name = std::string(val->name), 295 | .id = val->id, 296 | .type = match::to(val->type), 297 | .flags= val->flags 298 | }; 299 | #endif 300 | } 301 | 302 | Option option_next(const Option previous) noexcept { 303 | __curl_easyoption* value; 304 | 305 | #if __cplusplus >= 202002L 306 | value->name = previous.name.c_str(); 307 | value->id = previous.id; 308 | value->type = match::from(previous.type); 309 | value->flags= previous.flags; 310 | #else 311 | *value = __curl_easyoption { 312 | .name = previous.name.c_str(), 313 | .id = previous.id, 314 | .type = match::from(previous.type), 315 | .flags= previous.flags 316 | }; 317 | #endif 318 | 319 | auto val = const_cast<__curl_easyoption*>(curl_easy_option_next(value)); 320 | 321 | #if __cplusplus >= 202002L 322 | Option init; 323 | init.name = std::string(val->name); 324 | init.id = val->id; 325 | init.type = match::to(val->type); 326 | init.flags= val->flags; 327 | return init; 328 | #else 329 | return Option { 330 | .name = std::string(val->name), 331 | .id = val->id, 332 | .type = match::to(val->type), 333 | .flags= val->flags 334 | }; 335 | #endif 336 | } 337 | 338 | CURLcode pause(CURL4& handle, int bitmask) noexcept { 339 | return curl_easy_pause(handle.init, bitmask); 340 | } 341 | 342 | CURLcode perform(CURL4& easy_handle) noexcept { 343 | return curl_easy_perform(easy_handle.init); 344 | } 345 | 346 | template 347 | CURLcode recv(CURL4& handle, 348 | Buffer* buffer, 349 | std::size_t buffer_length, 350 | std::size_t* n) noexcept { 351 | return curl_easy_recv(handle.init, buffer, buffer_length, n); 352 | } 353 | 354 | void reset(CURL4& handle) noexcept { 355 | curl_easy_reset(handle.init); 356 | } 357 | 358 | template 359 | CURLcode send(CURL4& handle, 360 | const Buffer* buffer, 361 | std::size_t buffer_length, 362 | std::size_t* n) noexcept { 363 | return curl_easy_send(handle.init, buffer, buffer_length, n); 364 | } 365 | 366 | template 367 | CURLcode setopt(CURL4& handle, CURLoption option, Param parameter) noexcept { 368 | if constexpr (std::is_same_v || std::is_same_v>) { 369 | return curl_easy_setopt(handle.init, option, parameter.c_str()); 370 | } else { return curl_easy_setopt(handle.init, option, parameter); } 371 | } 372 | 373 | const std::string strerror(CURLcode error) noexcept { 374 | return std::string(curl_easy_strerror(error)); 375 | } 376 | 377 | std::string unescape(CURL4& handle, 378 | std::string url, 379 | unsigned inlength, 380 | int* outlength) noexcept { 381 | return curl_easy_unescape(handle.init, url.c_str(), inlength, outlength); 382 | } 383 | 384 | CURLcode upkeep(CURL4& handle) noexcept { 385 | return curl_easy_upkeep(handle.init); 386 | } 387 | 388 | std::size_t writefunc(void *ptr, std::size_t size, std::size_t nmemb, std::string* s) noexcept { 389 | s->append(static_cast(ptr), size * nmemb); 390 | return size * nmemb; 391 | } 392 | } 393 | 394 | namespace form { 395 | // deprecated 396 | // deprecated 397 | 398 | class HTTPPost { 399 | public: 400 | __curl_httppost* init; 401 | public: 402 | HTTPPost() = default; 403 | ~HTTPPost()= default; 404 | }; 405 | 406 | template 407 | int get(HTTPPost& form, Param userp, __curl_formget_callback append) noexcept { 408 | return curl_formget(form.init, userp, append); 409 | } 410 | } 411 | 412 | // Not thread safe (for C++20 there will be new date utils) 413 | #ifdef CURL4CPP_ENABLE_CTIME 414 | namespace date { 415 | std::time_t get(std::string date, std::time_t* now) noexcept { 416 | return curl_getdate(date.data(), now); 417 | } 418 | } 419 | #endif // CURL4CPP_ENABLE_CTIME 420 | 421 | namespace global { 422 | enum SSLBackendTypes { 423 | CURL4SSLBACKEND_NONE = 0, 424 | CURL4SSLBACKEND_OPENSSL = 1, 425 | CURL4SSLBACKEND_GNUTLS = 2, 426 | CURL4SSLBACKEND_NSS = 3, 427 | CURL4SSLBACKEND_GSKIT = 5, 428 | CURL4SSLBACKEND_POLARSSL = 6, 429 | CURL4SSLBACKEND_WOLFSSL = 7, 430 | CURL4SSLBACKEND_SCHANNEL = 8, 431 | CURL4SSLBACKEND_SECURETRANSPORT = 9, 432 | CURL4SSLBACKEND_AXTLS = 10, 433 | CURL4SSLBACKEND_MBEDTLS = 11, 434 | CURL4SSLBACKEND_MESALINK = 12, 435 | CURL4SSLBACKEND_BEARSSL = 13 436 | }; 437 | 438 | 439 | class SSLBackend { 440 | public: 441 | SSLBackendTypes id; 442 | std::string name; 443 | public: 444 | SSLBackend() = default; 445 | ~SSLBackend() = default; 446 | 447 | SSLBackendTypes get_id() { 448 | return this->id; 449 | } 450 | 451 | std::string get_name() { 452 | return this->name; 453 | } 454 | }; 455 | 456 | namespace ssl { 457 | enum class CURL4SSL { 458 | SET_OK, 459 | SET_UNKNOWN_BACKEND, 460 | SET_TOO_LATE, 461 | SET_NO_BACKENDS 462 | }; 463 | 464 | namespace match { 465 | CURL4SSL to(CURLsslset val) noexcept { 466 | switch(val) { 467 | case CURLSSLSET_OK: { 468 | return CURL4SSL::SET_OK; 469 | } 470 | 471 | case CURLSSLSET_UNKNOWN_BACKEND: { 472 | return CURL4SSL::SET_UNKNOWN_BACKEND; 473 | } 474 | 475 | case CURLSSLSET_TOO_LATE: { 476 | return CURL4SSL::SET_TOO_LATE; 477 | } 478 | 479 | case CURLSSLSET_NO_BACKENDS: { 480 | return CURL4SSL::SET_NO_BACKENDS; 481 | } 482 | } return CURL4SSL::SET_NO_BACKENDS; 483 | } 484 | } 485 | 486 | curl_sslbackend from(SSLBackendTypes type) noexcept { 487 | switch(type) { 488 | case CURL4SSLBACKEND_NONE: { 489 | return CURLSSLBACKEND_NONE; 490 | } 491 | 492 | case CURL4SSLBACKEND_OPENSSL: { 493 | return CURLSSLBACKEND_OPENSSL; 494 | } 495 | 496 | case CURL4SSLBACKEND_GNUTLS: { 497 | return CURLSSLBACKEND_GNUTLS; 498 | } 499 | 500 | case CURL4SSLBACKEND_NSS: { 501 | return CURLSSLBACKEND_NSS; 502 | } 503 | 504 | case CURL4SSLBACKEND_GSKIT: { 505 | return CURLSSLBACKEND_GSKIT; 506 | } 507 | 508 | case CURL4SSLBACKEND_POLARSSL: { 509 | return CURLSSLBACKEND_POLARSSL; 510 | } 511 | 512 | case CURL4SSLBACKEND_WOLFSSL: { 513 | return CURLSSLBACKEND_WOLFSSL; 514 | } 515 | 516 | case CURL4SSLBACKEND_SCHANNEL: { 517 | return CURLSSLBACKEND_SCHANNEL; 518 | } 519 | 520 | case CURL4SSLBACKEND_SECURETRANSPORT: { 521 | return CURLSSLBACKEND_SECURETRANSPORT; 522 | } 523 | 524 | case CURL4SSLBACKEND_AXTLS: { 525 | return CURLSSLBACKEND_AXTLS; 526 | } 527 | 528 | case CURL4SSLBACKEND_MBEDTLS: { 529 | return CURLSSLBACKEND_MBEDTLS; 530 | } 531 | 532 | case CURL4SSLBACKEND_MESALINK: { 533 | return CURLSSLBACKEND_MESALINK; 534 | } 535 | 536 | case CURL4SSLBACKEND_BEARSSL: { 537 | return CURLSSLBACKEND_BEARSSL; 538 | } 539 | } return CURLSSLBACKEND_NONE; 540 | } 541 | 542 | CURL4SSL set(SSLBackendTypes __id, std::string name, SSLBackend*** __avail) noexcept { 543 | auto __val = ***__avail; 544 | 545 | curl_ssl_backend*** val; 546 | 547 | #if __cplusplus >= 202002L 548 | (**val)->id = ssl::from(__val.id); 549 | (**val)->name= __val.name.c_str(); 550 | #else 551 | ***val = curl_ssl_backend { 552 | .id = ssl::from(__val.id), 553 | .name = __val.name.c_str() 554 | }; 555 | #endif 556 | 557 | return match::to(curl_global_sslset(ssl::from(__id), 558 | name.c_str(), const_cast(val))); 559 | } 560 | } 561 | 562 | void cleanup() noexcept { 563 | curl_global_cleanup(); 564 | } 565 | 566 | CURLcode init(long flags) noexcept { 567 | return curl_global_init(flags); 568 | } 569 | 570 | using __curl_malloc_callback = curl_malloc_callback; 571 | using __curl_free_callback = curl_free_callback; 572 | using __curl_realloc_callback= curl_realloc_callback; 573 | using __curl_strdup_callback = curl_strdup_callback; 574 | using __curl_calloc_callback = curl_calloc_callback; 575 | 576 | CURLcode init_mem(long flags, 577 | curl_malloc_callback m, 578 | curl_free_callback f, 579 | curl_realloc_callback r, 580 | curl_strdup_callback s, 581 | curl_calloc_callback c) noexcept { 582 | return curl_global_init_mem(flags, m, f, r, s, c); 583 | } 584 | } 585 | 586 | namespace mime { 587 | __curl_mimepart* addpart(__curl_mime* mime) noexcept { 588 | return curl_mime_addpart(mime); 589 | } 590 | 591 | CURLcode data(__curl_mimepart* part, const std::string data, std::size_t data_size) noexcept { 592 | return curl_mime_data(part, data.c_str(), data_size); 593 | } 594 | 595 | template 596 | CURLcode data_cb(__curl_mimepart* part, 597 | __curl_off_t* data_size, 598 | __curl_read_callback readfunc, 599 | __curl_seek_callback seekfunc, 600 | __curl_free_callback freefunc, Param arg) noexcept { 601 | return curl_mime_data_cb(part, data_size, readfunc, seekfunc, freefunc, arg); 602 | } 603 | 604 | CURLcode encoder(__curl_mimepart* part, std::string encoding) noexcept { 605 | return curl_mime_encoder(part, encoding.c_str()); 606 | } 607 | 608 | CURLcode filedata(__curl_mimepart* part, const std::string filename) noexcept { 609 | return curl_mime_filedata(part, filename.c_str()); 610 | } 611 | 612 | CURLcode filename(__curl_mimepart* part, const std::string filename) noexcept { 613 | return curl_mime_filename(part, filename.c_str()); 614 | } 615 | 616 | void free(__curl_mime*& mime) noexcept { 617 | curl_mime_free(mime); 618 | } 619 | 620 | CURLcode headers(__curl_mimepart* part, __curl_s_list* headers, int take_ownership) noexcept { 621 | return curl_mime_headers(part, headers, take_ownership); 622 | } 623 | 624 | __curl_mime* init(CURL4& handle) noexcept { 625 | return curl_mime_init(handle.init); 626 | } 627 | 628 | CURLcode name(__curl_mimepart* part, const std::string name) noexcept { 629 | return curl_mime_name(part, name.c_str()); 630 | } 631 | 632 | CURLcode subparts(__curl_mimepart* part, __curl_mime* subparts) noexcept { 633 | return curl_mime_subparts(part, subparts); 634 | } 635 | 636 | CURLcode type(__curl_mimepart* part, const std::string mimetype) noexcept { 637 | return curl_mime_type(part, mimetype.c_str()); 638 | } 639 | } 640 | 641 | namespace multi { 642 | using __CURLMcode = CURLMcode; 643 | using __CURLMSG = CURLMSG; 644 | using __CURLMoption = CURLMoption; 645 | 646 | enum class CURL4MsgType { 647 | MSG_NONE, 648 | MSG_DONE, 649 | MSG_LAST 650 | }; 651 | 652 | enum class CURL4MCodeType { 653 | CALL_MULTI_PERFORM = -1, 654 | OK, 655 | BAD_HANDLE, 656 | BAD_EASY_HANDLE, 657 | OUT_OF_MEMORY, 658 | INTERNAL_ERROR, 659 | BAD_SOCKET, 660 | UNKNOWN_OPTION, 661 | ADDED_ALREADY, 662 | RECURSIVE_API_CALL, 663 | WAKEUP_FAILURE, 664 | BAD_FUNCTION_ARGUMENT, 665 | LAST 666 | }; 667 | 668 | namespace match { 669 | __CURLMcode from(CURL4MCodeType val) noexcept { 670 | switch(val) { 671 | case CURL4MCodeType::CALL_MULTI_PERFORM: { 672 | return CURLM_CALL_MULTI_PERFORM; 673 | } 674 | 675 | case CURL4MCodeType::OK: { 676 | return CURLM_OK; 677 | } 678 | 679 | case CURL4MCodeType::BAD_HANDLE: { 680 | return CURLM_BAD_HANDLE; 681 | } 682 | 683 | case CURL4MCodeType::BAD_EASY_HANDLE: { 684 | return CURLM_BAD_EASY_HANDLE; 685 | } 686 | 687 | case CURL4MCodeType::OUT_OF_MEMORY: { 688 | return CURLM_OUT_OF_MEMORY; 689 | } 690 | 691 | case CURL4MCodeType::INTERNAL_ERROR: { 692 | return CURLM_INTERNAL_ERROR; 693 | } 694 | 695 | case CURL4MCodeType::BAD_SOCKET: { 696 | return CURLM_BAD_SOCKET; 697 | } 698 | 699 | case CURL4MCodeType::UNKNOWN_OPTION: { 700 | return CURLM_UNKNOWN_OPTION; 701 | } 702 | 703 | case CURL4MCodeType::ADDED_ALREADY: { 704 | return CURLM_ADDED_ALREADY; 705 | } 706 | 707 | case CURL4MCodeType::RECURSIVE_API_CALL: { 708 | return CURLM_RECURSIVE_API_CALL; 709 | } 710 | 711 | case CURL4MCodeType::WAKEUP_FAILURE: { 712 | return CURLM_WAKEUP_FAILURE; 713 | } 714 | 715 | case CURL4MCodeType::BAD_FUNCTION_ARGUMENT: { 716 | return CURLM_BAD_FUNCTION_ARGUMENT; 717 | } 718 | 719 | case CURL4MCodeType::LAST: { 720 | return CURLM_LAST; 721 | } 722 | } return CURLM_LAST; 723 | } 724 | 725 | CURL4MCodeType to(__CURLMcode val) noexcept { 726 | switch(val) { 727 | case CURLM_CALL_MULTI_PERFORM: { 728 | return CURL4MCodeType::CALL_MULTI_PERFORM; 729 | } 730 | 731 | case CURLM_OK: { 732 | return CURL4MCodeType::OK; 733 | } 734 | 735 | case CURLM_BAD_HANDLE: { 736 | return CURL4MCodeType::BAD_HANDLE; 737 | } 738 | 739 | case CURLM_BAD_EASY_HANDLE: { 740 | return CURL4MCodeType::BAD_EASY_HANDLE; 741 | } 742 | 743 | case CURLM_OUT_OF_MEMORY: { 744 | return CURL4MCodeType::OUT_OF_MEMORY; 745 | } 746 | 747 | case CURLM_INTERNAL_ERROR: { 748 | return CURL4MCodeType::INTERNAL_ERROR; 749 | } 750 | 751 | case CURLM_BAD_SOCKET: { 752 | return CURL4MCodeType::BAD_SOCKET; 753 | } 754 | 755 | case CURLM_UNKNOWN_OPTION: { 756 | return CURL4MCodeType::UNKNOWN_OPTION; 757 | } 758 | 759 | case CURLM_ADDED_ALREADY: { 760 | return CURL4MCodeType::ADDED_ALREADY; 761 | } 762 | 763 | case CURLM_RECURSIVE_API_CALL: { 764 | return CURL4MCodeType::RECURSIVE_API_CALL; 765 | } 766 | 767 | case CURLM_WAKEUP_FAILURE: { 768 | return CURL4MCodeType::WAKEUP_FAILURE; 769 | } 770 | 771 | case CURLM_BAD_FUNCTION_ARGUMENT: { 772 | return CURL4MCodeType::BAD_FUNCTION_ARGUMENT; 773 | } 774 | 775 | case CURLM_LAST: { 776 | return CURL4MCodeType::LAST; 777 | } 778 | } return CURL4MCodeType::LAST; 779 | } 780 | 781 | __CURLMSG from(CURL4MsgType val) noexcept { 782 | switch(val) { 783 | case CURL4MsgType::MSG_NONE: { 784 | return CURLMSG_NONE; 785 | } 786 | 787 | case CURL4MsgType::MSG_DONE: { 788 | return CURLMSG_DONE; 789 | } 790 | 791 | case CURL4MsgType::MSG_LAST: { 792 | return CURLMSG_LAST; 793 | } 794 | } return CURLMSG_NONE; 795 | } 796 | 797 | CURL4MsgType to(__CURLMSG val) noexcept { 798 | switch(val) { 799 | case CURLMSG_NONE: { 800 | return CURL4MsgType::MSG_NONE; 801 | } 802 | 803 | case CURLMSG_DONE: { 804 | return CURL4MsgType::MSG_DONE; 805 | } 806 | 807 | case CURLMSG_LAST: { 808 | return CURL4MsgType::MSG_LAST; 809 | } 810 | } return CURL4MsgType::MSG_NONE; 811 | } 812 | } 813 | 814 | class CURL4M { 815 | public: 816 | CURLM* init; 817 | public: 818 | CURL4M() = default; 819 | ~CURL4M()= default; 820 | }; 821 | 822 | template 823 | class CURL4Msg { 824 | public: 825 | CURL4MsgType msg; 826 | CURL4* handle; 827 | 828 | union { 829 | Value* whatever; 830 | CURLcode result; 831 | } data; 832 | public: 833 | CURL4Msg() = default; 834 | ~CURL4Msg()= default; 835 | }; 836 | 837 | CURL4MCodeType add_handle(CURL4M& multi_handle, CURL4& handle) noexcept { 838 | return match::to(curl_multi_add_handle(multi_handle.init, handle.init)); 839 | } 840 | 841 | template 842 | CURL4MCodeType assign(CURL4M& multi_handle, __curl_socket sockfd, Param arg) noexcept { 843 | return match::to(curl_multi_assign(multi_handle.init, sockfd, arg)); 844 | } 845 | 846 | CURL4MCodeType cleanup(CURL4M& multi_handle) noexcept { 847 | return match::to(curl_multi_cleanup(multi_handle.init)); 848 | } 849 | 850 | CURL4MCodeType fdset(CURL4M& multi_handle, 851 | __fd_set* read_fd_set, 852 | __fd_set* write_fd_set, 853 | __fd_set* exc_fd_set, 854 | int* max_fd) noexcept { 855 | return match::to(curl_multi_fdset(multi_handle.init, read_fd_set, write_fd_set, exc_fd_set, max_fd)); 856 | } 857 | 858 | template 859 | CURL4Msg info_read(CURL4M& multi_handle, int* msgs_in_queue) noexcept { 860 | auto val = curl_multi_info_read(multi_handle.init, msgs_in_queue); 861 | 862 | #if __cplusplus >= 202002L 863 | CURL4Msg init; 864 | CURL4 __init__; init.init = val->easy_handle; 865 | init.msg = match::to(val->msg); 866 | init.handle= __init__; 867 | init.data = val->data; 868 | return init; 869 | #else 870 | return CURL4Msg { 871 | .msg = match::to(val->msg), 872 | .handle = CURL4 { .init = val->easy_handle }, 873 | .data = val->data 874 | }; 875 | #endif 876 | } 877 | 878 | CURL4M init() noexcept { 879 | #if __cplusplus >= 202002L 880 | CURL4M init; 881 | init.init = curl_multi_init(); 882 | return init; 883 | #else 884 | return CURL4M { 885 | .init = curl_multi_init() 886 | }; 887 | #endif 888 | } 889 | 890 | CURL4MCodeType perform(CURL4M& multi_handle, int* running_handles) noexcept { 891 | return match::to(curl_multi_perform(multi_handle.init, running_handles)); 892 | } 893 | 894 | CURL4MCodeType remove_handle(CURL4M& mutli_handle, CURL4& handle) noexcept { 895 | return match::to(curl_multi_remove_handle(mutli_handle.init, handle.init)); 896 | } 897 | 898 | template 899 | CURL4MCodeType setopt(CURL4M& multi_handle, __CURLMoption option, Param parameter) noexcept { 900 | return match::to(curl_multi_setopt(multi_handle.init, option, parameter)); 901 | } 902 | 903 | CURL4MCodeType socket_action(CURL4M& multi_handle, 904 | __curl_socket sockfd, 905 | int ev_bitmask, 906 | int* running_handles) noexcept { 907 | return match::to(curl_multi_socket_action(multi_handle.init, sockfd, ev_bitmask, running_handles)); 908 | } 909 | 910 | const std::string strerror(__CURLMcode error_num) noexcept { 911 | return std::string(curl_multi_strerror(error_num)); 912 | } 913 | 914 | CURL4MCodeType timeout(CURL4M& multi_handle, long* timeout) noexcept { 915 | return match::to(curl_multi_timeout(multi_handle.init, timeout)); 916 | } 917 | 918 | CURL4MCodeType poll(CURL4M& multi_handle, 919 | __curl_waitfd extra_fds[], 920 | unsigned extra_nfds, 921 | int timeout_ms, 922 | int* numfds) noexcept { 923 | return match::to(curl_multi_poll(multi_handle.init, extra_fds, extra_nfds, timeout_ms, numfds)); 924 | } 925 | 926 | CURL4MCodeType wait(CURL4M& multi_handle, 927 | __curl_waitfd extra_fds[], 928 | unsigned extra_nfds, 929 | int timeout_ms, 930 | int* numfds) noexcept { 931 | return match::to(curl_multi_wait(multi_handle.init, extra_fds, extra_nfds, timeout_ms, numfds)); 932 | } 933 | 934 | CURL4MCodeType wakeup(CURL4M& multi_handle) noexcept { 935 | return match::to(curl_multi_wakeup(multi_handle.init)); 936 | } 937 | } 938 | 939 | namespace share { 940 | using __CURLSH = CURLSH; 941 | using __CURLSHcode = CURLSHcode; 942 | using __CURLSHoption = CURLSHoption; 943 | 944 | enum class CURL4SHCodeType { 945 | OK, 946 | BAD_OPTION, 947 | IN_USE, 948 | INVALID, 949 | NOMEM, 950 | NOT_BUILT_IN, 951 | LAST 952 | }; 953 | 954 | enum class CURL4SHOptionType { 955 | NONE, 956 | SHARE, 957 | UNSHARE, 958 | LOCKFUNC, 959 | UNLOCKFUNC, 960 | USERDATA, 961 | LAST 962 | }; 963 | 964 | namespace match { 965 | __CURLSHcode from(CURL4SHCodeType val) noexcept { 966 | switch(val) { 967 | case CURL4SHCodeType::OK: { 968 | return CURLSHE_OK; 969 | } 970 | 971 | case CURL4SHCodeType::BAD_OPTION: { 972 | return CURLSHE_BAD_OPTION; 973 | } 974 | 975 | case CURL4SHCodeType::IN_USE: { 976 | return CURLSHE_IN_USE; 977 | } 978 | 979 | case CURL4SHCodeType::INVALID: { 980 | return CURLSHE_INVALID; 981 | } 982 | 983 | case CURL4SHCodeType::NOMEM: { 984 | return CURLSHE_NOMEM; 985 | } 986 | 987 | case CURL4SHCodeType::NOT_BUILT_IN: { 988 | return CURLSHE_NOT_BUILT_IN; 989 | } 990 | 991 | case CURL4SHCodeType::LAST: { 992 | return CURLSHE_LAST; 993 | } 994 | } return CURLSHE_LAST; 995 | } 996 | 997 | CURL4SHCodeType to(__CURLSHcode val) noexcept { 998 | switch(val) { 999 | case CURLSHE_OK: { 1000 | return CURL4SHCodeType::OK; 1001 | } 1002 | 1003 | case CURLSHE_BAD_OPTION: { 1004 | return CURL4SHCodeType::BAD_OPTION; 1005 | } 1006 | 1007 | case CURLSHE_IN_USE: { 1008 | return CURL4SHCodeType::IN_USE; 1009 | } 1010 | 1011 | case CURLSHE_INVALID: { 1012 | return CURL4SHCodeType::INVALID; 1013 | } 1014 | 1015 | case CURLSHE_NOMEM: { 1016 | return CURL4SHCodeType::NOMEM; 1017 | } 1018 | 1019 | case CURLSHE_NOT_BUILT_IN: { 1020 | return CURL4SHCodeType::NOT_BUILT_IN; 1021 | } 1022 | 1023 | case CURLSHE_LAST: { 1024 | return CURL4SHCodeType::LAST; 1025 | } 1026 | } return CURL4SHCodeType::LAST; 1027 | } 1028 | 1029 | __CURLSHoption from(CURL4SHOptionType val) noexcept { 1030 | switch(val) { 1031 | case CURL4SHOptionType::NONE: { 1032 | return CURLSHOPT_NONE; 1033 | } 1034 | 1035 | case CURL4SHOptionType::SHARE: { 1036 | return CURLSHOPT_SHARE; 1037 | } 1038 | 1039 | case CURL4SHOptionType::UNSHARE: { 1040 | return CURLSHOPT_UNSHARE; 1041 | } 1042 | 1043 | case CURL4SHOptionType::LOCKFUNC: { 1044 | return CURLSHOPT_LOCKFUNC; 1045 | } 1046 | 1047 | case CURL4SHOptionType::UNLOCKFUNC: { 1048 | return CURLSHOPT_UNLOCKFUNC; 1049 | } 1050 | 1051 | case CURL4SHOptionType::USERDATA: { 1052 | return CURLSHOPT_USERDATA; 1053 | } 1054 | 1055 | case CURL4SHOptionType::LAST: { 1056 | return CURLSHOPT_LAST; 1057 | } 1058 | } return CURLSHOPT_LAST; 1059 | } 1060 | 1061 | CURL4SHOptionType to(__CURLSHoption val) noexcept { 1062 | switch(val) { 1063 | case CURLSHOPT_NONE: { 1064 | return CURL4SHOptionType::NONE; 1065 | } 1066 | 1067 | case CURLSHOPT_SHARE: { 1068 | return CURL4SHOptionType::SHARE; 1069 | } 1070 | 1071 | case CURLSHOPT_UNSHARE: { 1072 | return CURL4SHOptionType::UNSHARE; 1073 | } 1074 | 1075 | case CURLSHOPT_LOCKFUNC: { 1076 | return CURL4SHOptionType::LOCKFUNC; 1077 | } 1078 | 1079 | case CURLSHOPT_UNLOCKFUNC: { 1080 | return CURL4SHOptionType::USERDATA; 1081 | } 1082 | 1083 | case CURLSHOPT_USERDATA: { 1084 | return CURL4SHOptionType::USERDATA; 1085 | } 1086 | 1087 | case CURLSHOPT_LAST: { 1088 | return CURL4SHOptionType::LAST; 1089 | } 1090 | } return CURL4SHOptionType::LAST; 1091 | } 1092 | } 1093 | 1094 | CURL4SHCodeType cleanup(__CURLSH* share_handle) noexcept { 1095 | return match::to(curl_share_cleanup(share_handle)); 1096 | } 1097 | 1098 | __CURLSH* init() noexcept { 1099 | return curl_share_init(); 1100 | } 1101 | 1102 | template 1103 | CURL4SHCodeType setopt(__CURLSH* share, CURLSHoption option, Param parameter) noexcept { 1104 | return match::to(curl_share_setopt(share, option, parameter)); 1105 | } 1106 | 1107 | const std::string strerror(CURL4SHCodeType errornum) noexcept { 1108 | return std::string(curl_share_strerror(match::from(errornum))); 1109 | } 1110 | } 1111 | 1112 | namespace slist { 1113 | __curl_s_list* append(__curl_s_list* list, const std::string str) noexcept { 1114 | return curl_slist_append(list, str.c_str()); 1115 | } 1116 | 1117 | void free_all(__curl_s_list* list) noexcept { 1118 | curl_slist_free_all(list); 1119 | } 1120 | } 1121 | 1122 | namespace url { 1123 | using __CURLU = CURLU; 1124 | using __CURLUcode = CURLUcode; 1125 | using __CURLUPart = CURLUPart; 1126 | 1127 | __CURLU* init() noexcept { 1128 | return curl_url(); 1129 | } 1130 | 1131 | void cleanup(__CURLU* handle) noexcept { 1132 | curl_url_cleanup(handle); 1133 | } 1134 | 1135 | __CURLU* dup(__CURLU* inhandle) noexcept { 1136 | return curl_url_dup(inhandle); 1137 | } 1138 | 1139 | __CURLUcode get(__CURLU* url, 1140 | __CURLUPart what, 1141 | char** part, // std::string 1142 | unsigned flags) noexcept { 1143 | return curl_url_get(url, what, part, flags); 1144 | } 1145 | 1146 | __CURLUcode set(__CURLU* url, 1147 | __CURLUPart part, 1148 | const std::string content, 1149 | unsigned flags) noexcept { 1150 | return curl_url_set(url, part, content.c_str(), flags); 1151 | } 1152 | } 1153 | 1154 | namespace version { 1155 | using __CURLversion = CURLversion; 1156 | 1157 | enum class CURL4Version { 1158 | FIRST, 1159 | SECOND, 1160 | THIRD, 1161 | FOURTH, 1162 | FIFTH, 1163 | SIXTH, 1164 | SEVENTH, 1165 | EIGHTH, 1166 | 1167 | #ifdef CURLVERSION_NINTH 1168 | NINTH, 1169 | #endif 1170 | 1171 | LAST 1172 | }; 1173 | 1174 | class CURL4VersionInfoData { 1175 | public: 1176 | CURL4Version age; 1177 | 1178 | std::string version; 1179 | unsigned version_num; 1180 | 1181 | std::string host; 1182 | int features; 1183 | 1184 | std::string ssl_version; 1185 | long ssl_version_num; 1186 | 1187 | std::string libz_version; 1188 | std::string protocols; 1189 | 1190 | std::string ares; 1191 | int ares_num; 1192 | 1193 | std::string libidn; 1194 | 1195 | int iconv_ver_num; 1196 | 1197 | std::string libssh_version; 1198 | 1199 | unsigned brotli_ver_num; 1200 | 1201 | std::string brotli_version; 1202 | 1203 | unsigned nghttp2_ver_num; 1204 | 1205 | std::string nghttp2_version; 1206 | std::string quic_version; 1207 | 1208 | std::string cainfo; 1209 | std::string capath; 1210 | 1211 | unsigned zstd_version_num; 1212 | 1213 | std::string zstd_version; 1214 | std::string hyper_version; 1215 | // const std::string gsasl_version; 1216 | public: 1217 | CURL4VersionInfoData() = default; 1218 | ~CURL4VersionInfoData()= default; 1219 | }; 1220 | 1221 | namespace match { 1222 | __CURLversion from(CURL4Version val) noexcept { 1223 | switch(val) { 1224 | case CURL4Version::FIRST: { 1225 | return CURLVERSION_FIRST; 1226 | } 1227 | 1228 | case CURL4Version::SECOND: { 1229 | return CURLVERSION_SECOND; 1230 | } 1231 | 1232 | case CURL4Version::THIRD: { 1233 | return CURLVERSION_THIRD; 1234 | } 1235 | 1236 | case CURL4Version::FOURTH: { 1237 | return CURLVERSION_FOURTH; 1238 | } 1239 | 1240 | case CURL4Version::FIFTH: { 1241 | return CURLVERSION_FIFTH; 1242 | } 1243 | 1244 | case CURL4Version::SIXTH: { 1245 | return CURLVERSION_SIXTH; 1246 | } 1247 | 1248 | case CURL4Version::SEVENTH: { 1249 | return CURLVERSION_SEVENTH; 1250 | } 1251 | 1252 | case CURL4Version::EIGHTH: { 1253 | return CURLVERSION_EIGHTH; 1254 | } 1255 | 1256 | #ifdef CURLVERSION_NINTH 1257 | case CURL4Version::NINTH: { 1258 | return CURLVERSION_NINTH; 1259 | } 1260 | #endif 1261 | 1262 | case CURL4Version::LAST: { 1263 | return CURLVERSION_LAST; 1264 | } 1265 | } return CURLVERSION_LAST; 1266 | } 1267 | 1268 | CURL4Version to(__CURLversion val) noexcept { 1269 | switch(val) { 1270 | case CURLVERSION_FIRST: { 1271 | return CURL4Version::FIRST; 1272 | } 1273 | 1274 | case CURLVERSION_SECOND: { 1275 | return CURL4Version::SECOND; 1276 | } 1277 | 1278 | case CURLVERSION_THIRD: { 1279 | return CURL4Version::THIRD; 1280 | } 1281 | 1282 | case CURLVERSION_FOURTH: { 1283 | return CURL4Version::FOURTH; 1284 | } 1285 | 1286 | case CURLVERSION_FIFTH: { 1287 | return CURL4Version::FIFTH; 1288 | } 1289 | 1290 | case CURLVERSION_SIXTH: { 1291 | return CURL4Version::SIXTH; 1292 | } 1293 | 1294 | case CURLVERSION_SEVENTH: { 1295 | return CURL4Version::SEVENTH; 1296 | } 1297 | 1298 | case CURLVERSION_EIGHTH: { 1299 | return CURL4Version::EIGHTH; 1300 | } 1301 | 1302 | #ifdef CURLVERSION_NINTH 1303 | case CURLVERSION_NINTH: { 1304 | return CURL4Version::NINTH; 1305 | } 1306 | #endif 1307 | 1308 | case CURLVERSION_LAST: { 1309 | return CURL4Version::LAST; 1310 | } 1311 | } return CURL4Version::LAST; 1312 | } 1313 | } 1314 | 1315 | std::string version() noexcept { 1316 | return std::string(curl_version()); 1317 | } 1318 | 1319 | CURL4VersionInfoData version_info(CURL4Version age) noexcept { 1320 | auto val = curl_version_info(match::from(age)); 1321 | 1322 | #if __cplusplus >= 202002L 1323 | CURL4VersionInfoData init; 1324 | 1325 | init.age = match::to(val->age); 1326 | 1327 | init.version = std::string(val->version); 1328 | init.version_num = val->version_num; 1329 | 1330 | init.host = std::string(val->host); 1331 | init.features = val->features; 1332 | 1333 | init.ssl_version = std::string(val->ssl_version); 1334 | init.ssl_version_num = val->ssl_version_num; 1335 | 1336 | init.libz_version = std::string(val->libz_version); 1337 | init.protocols = std::string(reinterpret_cast(val->protocols)); 1338 | 1339 | init.ares = std::string(val->ares); 1340 | init.ares_num = val->ares_num; 1341 | 1342 | init.libidn = std::string(val->libidn); 1343 | 1344 | init.iconv_ver_num = val->iconv_ver_num; 1345 | 1346 | init.libssh_version = std::string(val->libssh_version); 1347 | init.brotli_ver_num = val->brotli_ver_num; 1348 | 1349 | init.brotli_version = std::string(val->brotli_version); 1350 | 1351 | init.nghttp2_ver_num = val->nghttp2_ver_num; 1352 | 1353 | init.nghttp2_version = std::string(val->nghttp2_version); 1354 | init.quic_version = std::string(val->quic_version); 1355 | 1356 | init.cainfo = std::string(val->cainfo); 1357 | init.capath = std::string(val->capath); 1358 | 1359 | init.zstd_version_num = val->zstd_ver_num; 1360 | 1361 | init.zstd_version = std::string(val->zstd_version); 1362 | 1363 | return init; 1364 | #else 1365 | return CURL4VersionInfoData { 1366 | .age = match::to(val->age), 1367 | 1368 | .version = std::string(val->version), 1369 | .version_num = val->version_num, 1370 | 1371 | .host = std::string(val->host), 1372 | .features = val->features, 1373 | 1374 | .ssl_version = std::string(val->ssl_version), 1375 | .ssl_version_num = val->ssl_version_num, 1376 | 1377 | .libz_version = std::string(val->libz_version), 1378 | .protocols = std::string(reinterpret_cast(val->protocols)), 1379 | 1380 | .ares = std::string(val->ares), 1381 | .ares_num = val->ares_num, 1382 | 1383 | .libidn = std::string(val->libidn), 1384 | 1385 | .iconv_ver_num = val->iconv_ver_num, 1386 | 1387 | .libssh_version = std::string(val->libssh_version), 1388 | .brotli_ver_num = val->brotli_ver_num, 1389 | 1390 | .brotli_version = std::string(val->brotli_version), 1391 | 1392 | .nghttp2_ver_num = val->nghttp2_ver_num, 1393 | 1394 | .nghttp2_version = std::string(val->nghttp2_version), 1395 | .quic_version = std::string(val->quic_version), 1396 | 1397 | .cainfo = std::string(val->cainfo), 1398 | .capath = std::string(val->capath), 1399 | 1400 | .zstd_version_num = val->zstd_ver_num, 1401 | 1402 | .zstd_version = std::string(val->zstd_version), 1403 | // .hyper_version = std::string(val->hyper_version) 1404 | }; 1405 | #endif 1406 | } 1407 | } 1408 | 1409 | void free(char*& ptr) noexcept { 1410 | curl_free(ptr); 1411 | } 1412 | } 1413 | 1414 | #endif // CURL4CPP_CURL4_HPP 1415 | --------------------------------------------------------------------------------