1
1
/*
2
2
3
3
Modern, non-blocking and exception free HTTP Client library for C++ (17+)
4
- version 1.4 .0
4
+ version 1.5 .0
5
5
https://github.com/leventkaragol/libcpp-http-client
6
6
7
7
If you encounter any issues, please submit a ticket at https://github.com/leventkaragol/libcpp-http-client/issues
@@ -134,7 +134,6 @@ namespace lklibs
134
134
{
135
135
initialized = true ;
136
136
137
- // Cleanup is called at program exit.
138
137
std::atexit (cleanup);
139
138
}
140
139
}
@@ -303,6 +302,18 @@ namespace lklibs
303
302
return *this ;
304
303
}
305
304
305
+ /* *
306
+ * @brief The callback that will be triggered when each piece (chunk) of incoming data is processed
307
+ *
308
+ * @param callback: Callback function that will be called with the data and its length
309
+ */
310
+ HttpRequest& onDataReceived (std::function<void (const unsigned char * data, size_t dataLength)> callback) noexcept
311
+ {
312
+ dataCallback = std::move (callback);
313
+
314
+ return *this ;
315
+ }
316
+
306
317
/* *
307
318
* @brief Convert the request to a cURL command string
308
319
* This can be useful for debugging or logging purposes
@@ -394,7 +405,7 @@ namespace lklibs
394
405
395
406
struct CurlDeleter
396
407
{
397
- void operator ()(CURL* ptr)
408
+ void operator ()(CURL* ptr) const
398
409
{
399
410
if (ptr)
400
411
{
@@ -405,7 +416,7 @@ namespace lklibs
405
416
406
417
struct CurlSlistDeleter
407
418
{
408
- void operator ()(curl_slist* ptr)
419
+ void operator ()(curl_slist* ptr) const
409
420
{
410
421
if (ptr)
411
422
{
@@ -414,6 +425,8 @@ namespace lklibs
414
425
}
415
426
};
416
427
428
+ std::function<void (const unsigned char * data, size_t dataLength)> dataCallback;
429
+
417
430
std::future<HttpResult> sendRequest () noexcept
418
431
{
419
432
return std::async (std::launch::async, [this ]() -> HttpResult
@@ -436,17 +449,17 @@ namespace lklibs
436
449
437
450
std::string stringBuffer;
438
451
std::vector<unsigned char > binaryBuffer;
439
- int statusCode = 0 ;
452
+ long statusCode = 0 ;
440
453
441
454
curl_easy_setopt (curl.get (), CURLOPT_HTTPHEADER, headerList.get ());
442
455
curl_easy_setopt (curl.get (), CURLOPT_URL, this ->url .c_str ());
443
456
curl_easy_setopt (curl.get (), CURLOPT_CUSTOMREQUEST, this ->method .c_str ());
444
457
curl_easy_setopt (curl.get (), CURLOPT_SSL_VERIFYPEER, this ->sslErrorsWillBeIgnored ? 0L : 1L );
445
458
curl_easy_setopt (curl.get (), CURLOPT_SSL_VERIFYHOST, this ->sslErrorsWillBeIgnored ? 0L : 1L );
446
- curl_easy_setopt (curl.get (), CURLOPT_SSLVERSION, static_cast <int >(this ->tlsVersion ));
459
+ curl_easy_setopt (curl.get (), CURLOPT_SSLVERSION, static_cast <long >(this ->tlsVersion ));
447
460
curl_easy_setopt (curl.get (), CURLOPT_TIMEOUT, this ->timeout );
448
- curl_easy_setopt (curl.get (), CURLOPT_MAX_SEND_SPEED_LARGE, this ->uploadBandwidthLimit );
449
- curl_easy_setopt (curl.get (), CURLOPT_MAX_RECV_SPEED_LARGE, this ->downloadBandwidthLimit );
461
+ curl_easy_setopt (curl.get (), CURLOPT_MAX_SEND_SPEED_LARGE, static_cast < curl_off_t >( this ->uploadBandwidthLimit ) );
462
+ curl_easy_setopt (curl.get (), CURLOPT_MAX_RECV_SPEED_LARGE, static_cast < curl_off_t >( this ->downloadBandwidthLimit ) );
450
463
451
464
if (!this ->userAgent .empty ())
452
465
{
@@ -458,7 +471,12 @@ namespace lklibs
458
471
curl_easy_setopt (curl.get (), CURLOPT_POSTFIELDS, this ->payload .c_str ());
459
472
}
460
473
461
- if (this ->returnFormat == ReturnFormat::BINARY)
474
+ if (dataCallback)
475
+ {
476
+ curl_easy_setopt (curl.get (), CURLOPT_WRITEFUNCTION, streamingWriteCallback);
477
+ curl_easy_setopt (curl.get (), CURLOPT_WRITEDATA, this );
478
+ }
479
+ else if (this ->returnFormat == ReturnFormat::BINARY)
462
480
{
463
481
curl_easy_setopt (curl.get (), CURLOPT_WRITEFUNCTION, binaryWriteCallback);
464
482
curl_easy_setopt (curl.get (), CURLOPT_WRITEDATA, &binaryBuffer);
@@ -469,35 +487,58 @@ namespace lklibs
469
487
curl_easy_setopt (curl.get (), CURLOPT_WRITEDATA, &stringBuffer);
470
488
}
471
489
472
- CURLcode res = curl_easy_perform (curl.get ());
490
+ const auto res = curl_easy_perform (curl.get ());
473
491
curl_easy_getinfo (curl.get (), CURLINFO_RESPONSE_CODE, &statusCode);
474
492
475
493
if (res == CURLE_OK && statusCode >= 200 && statusCode < 300 )
476
494
{
477
- return {true , stringBuffer, binaryBuffer, statusCode, " " };
495
+ return {
496
+ true ,
497
+ std::move (stringBuffer),
498
+ std::move (binaryBuffer),
499
+ static_cast <int >(statusCode),
500
+ " "
501
+ };
478
502
}
479
503
else
480
504
{
481
- std::string errorMessage = curl_easy_strerror (res);
482
-
505
+ std::string err = curl_easy_strerror (res);
483
506
if (res == CURLE_OK)
484
507
{
485
- errorMessage = " HTTP Error: " + std::to_string (statusCode);
508
+ err = " HTTP Error: " + std::to_string (statusCode);
486
509
}
487
-
488
- return {false , stringBuffer, binaryBuffer, statusCode, errorMessage};
510
+ return {
511
+ false ,
512
+ std::move (stringBuffer),
513
+ std::move (binaryBuffer),
514
+ static_cast <int >(statusCode),
515
+ std::move (err)
516
+ };
489
517
}
490
518
});
491
519
}
492
520
493
- static size_t textWriteCallback (void * contents, size_t size, size_t nmemb, void * userp)
521
+ static size_t streamingWriteCallback (const void * contents, const size_t size, size_t nmemb, void * userp)
522
+ {
523
+ const auto * self = static_cast <HttpRequest*>(userp);
524
+
525
+ const size_t total = size * nmemb;
526
+
527
+ const auto * data = static_cast <const unsigned char *>(contents);
528
+
529
+ self->dataCallback (data, total);
530
+
531
+ return total;
532
+ }
533
+
534
+ static size_t textWriteCallback (void * contents, const size_t size, size_t nmemb, void * userp)
494
535
{
495
- (( std::string*) userp)->append (( char *) contents, size * nmemb);
536
+ static_cast < std::string*>( userp)->append (static_cast < char *>( contents) , size * nmemb);
496
537
497
538
return size * nmemb;
498
539
}
499
540
500
- static size_t binaryWriteCallback (void * contents, size_t size, size_t nmemb, void * userp)
541
+ static size_t binaryWriteCallback (void * contents, const size_t size, size_t nmemb, void * userp)
501
542
{
502
543
auto & buffer = *static_cast <std::vector<unsigned char >*>(userp);
503
544
0 commit comments