@@ -219,12 +219,21 @@ void GetTrafficData(CURL* handle, uint64_t& upload_bytes,
219
219
download_bytes += headers_size;
220
220
}
221
221
222
+ #if CURL_AT_LEAST_VERSION(7, 55, 0)
223
+ off_t length_downloaded = 0 ;
224
+ if (curl_easy_getinfo (handle, CURLINFO_SIZE_DOWNLOAD_T, &length_downloaded) ==
225
+ CURLE_OK &&
226
+ length_downloaded > 0 ) {
227
+ download_bytes += length_downloaded;
228
+ }
229
+ #else
222
230
double length_downloaded;
223
231
if (curl_easy_getinfo (handle, CURLINFO_SIZE_DOWNLOAD, &length_downloaded) ==
224
232
CURLE_OK &&
225
233
length_downloaded > 0.0 ) {
226
234
download_bytes += length_downloaded;
227
235
}
236
+ #endif
228
237
229
238
long length_upload;
230
239
if (curl_easy_getinfo (handle, CURLINFO_REQUEST_SIZE, &length_upload) ==
@@ -564,40 +573,42 @@ ErrorCode NetworkCurl::SendImplementation(
564
573
handle->chunk = curl_slist_append (handle->chunk , sstrm.str ().c_str ());
565
574
}
566
575
576
+ CURL* curl_handle = handle->handle ;
577
+
567
578
if (verbose_) {
568
- curl_easy_setopt (handle-> handle , CURLOPT_VERBOSE, 1L );
579
+ curl_easy_setopt (curl_handle , CURLOPT_VERBOSE, 1L );
569
580
if (stderr_ != nullptr ) {
570
- curl_easy_setopt (handle-> handle , CURLOPT_STDERR, stderr_);
581
+ curl_easy_setopt (curl_handle , CURLOPT_STDERR, stderr_);
571
582
}
572
583
} else {
573
- curl_easy_setopt (handle-> handle , CURLOPT_VERBOSE, 0L );
584
+ curl_easy_setopt (curl_handle , CURLOPT_VERBOSE, 0L );
574
585
}
575
586
576
- curl_easy_setopt (handle-> handle , CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
587
+ curl_easy_setopt (curl_handle , CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
577
588
578
589
const std::string& url = request.GetUrl ();
579
- curl_easy_setopt (handle-> handle , CURLOPT_URL, url.c_str ());
590
+ curl_easy_setopt (curl_handle , CURLOPT_URL, url.c_str ());
580
591
auto verb = request.GetVerb ();
581
592
if (verb == NetworkRequest::HttpVerb::POST ||
582
593
verb == NetworkRequest::HttpVerb::PUT ||
583
594
verb == NetworkRequest::HttpVerb::PATCH) {
584
595
if (verb == NetworkRequest::HttpVerb::POST) {
585
- curl_easy_setopt (handle-> handle , CURLOPT_POST, 1L );
596
+ curl_easy_setopt (curl_handle , CURLOPT_POST, 1L );
586
597
} else if (verb == NetworkRequest::HttpVerb::PUT) {
587
598
// http://stackoverflow.com/questions/7569826/send-string-in-put-request-with-libcurl
588
- curl_easy_setopt (handle-> handle , CURLOPT_CUSTOMREQUEST, " PUT" );
599
+ curl_easy_setopt (curl_handle , CURLOPT_CUSTOMREQUEST, " PUT" );
589
600
} else if (verb == NetworkRequest::HttpVerb::PATCH) {
590
- curl_easy_setopt (handle-> handle , CURLOPT_CUSTOMREQUEST, " PATCH" );
601
+ curl_easy_setopt (curl_handle , CURLOPT_CUSTOMREQUEST, " PATCH" );
591
602
}
592
603
} else if (verb == NetworkRequest::HttpVerb::DEL) {
593
- curl_easy_setopt (handle-> handle , CURLOPT_CUSTOMREQUEST, " DELETE" );
604
+ curl_easy_setopt (curl_handle , CURLOPT_CUSTOMREQUEST, " DELETE" );
594
605
} else if (verb == NetworkRequest::HttpVerb::OPTIONS) {
595
- curl_easy_setopt (handle-> handle , CURLOPT_CUSTOMREQUEST, " OPTIONS" );
606
+ curl_easy_setopt (curl_handle , CURLOPT_CUSTOMREQUEST, " OPTIONS" );
596
607
} else { // GET or HEAD
597
- curl_easy_setopt (handle-> handle , CURLOPT_POST, 0L );
608
+ curl_easy_setopt (curl_handle , CURLOPT_POST, 0L );
598
609
599
610
if (verb == NetworkRequest::HttpVerb::HEAD) {
600
- curl_easy_setopt (handle-> handle , CURLOPT_NOBODY, 1L );
611
+ curl_easy_setopt (curl_handle , CURLOPT_NOBODY, 1L );
601
612
}
602
613
}
603
614
@@ -606,32 +617,30 @@ ErrorCode NetworkCurl::SendImplementation(
606
617
// These can also be used to add body data to a CURLOPT_CUSTOMREQUEST
607
618
// such as delete.
608
619
if (handle->body && !handle->body ->empty ()) {
609
- curl_easy_setopt (handle-> handle , CURLOPT_POSTFIELDSIZE,
620
+ curl_easy_setopt (curl_handle , CURLOPT_POSTFIELDSIZE,
610
621
handle->body ->size ());
611
- curl_easy_setopt (handle->handle , CURLOPT_POSTFIELDS,
612
- &handle->body ->front ());
622
+ curl_easy_setopt (curl_handle, CURLOPT_POSTFIELDS, &handle->body ->front ());
613
623
} else {
614
624
// Some services (eg. Google) require the field size even if zero
615
- curl_easy_setopt (handle-> handle , CURLOPT_POSTFIELDSIZE, 0L );
625
+ curl_easy_setopt (curl_handle , CURLOPT_POSTFIELDSIZE, 0L );
616
626
}
617
627
}
618
628
619
629
const auto & proxy = config.GetProxySettings ();
620
630
if (proxy.GetType () != NetworkProxySettings::Type::NONE) {
621
- curl_easy_setopt (handle->handle , CURLOPT_PROXY,
622
- proxy.GetHostname ().c_str ());
623
- curl_easy_setopt (handle->handle , CURLOPT_PROXYPORT, proxy.GetPort ());
631
+ curl_easy_setopt (curl_handle, CURLOPT_PROXY, proxy.GetHostname ().c_str ());
632
+ curl_easy_setopt (curl_handle, CURLOPT_PROXYPORT, proxy.GetPort ());
624
633
const auto proxy_type = proxy.GetType ();
625
634
if (proxy_type != NetworkProxySettings::Type::HTTP) {
626
- curl_easy_setopt (handle-> handle , CURLOPT_PROXYTYPE,
635
+ curl_easy_setopt (curl_handle , CURLOPT_PROXYTYPE,
627
636
ToCurlProxyType (proxy_type));
628
637
}
629
638
630
639
// We expect that both fields are empty or filled
631
640
if (!proxy.GetUsername ().empty () && !proxy.GetPassword ().empty ()) {
632
- curl_easy_setopt (handle-> handle , CURLOPT_PROXYUSERNAME,
641
+ curl_easy_setopt (curl_handle , CURLOPT_PROXYUSERNAME,
633
642
proxy.GetUsername ().c_str ());
634
- curl_easy_setopt (handle-> handle , CURLOPT_PROXYPASSWORD,
643
+ curl_easy_setopt (curl_handle , CURLOPT_PROXYPASSWORD,
635
644
proxy.GetPassword ().c_str ());
636
645
}
637
646
}
@@ -642,26 +651,26 @@ ErrorCode NetworkCurl::SendImplementation(
642
651
const std::string& dns_list = dns_servers.size () == 1
643
652
? dns_servers.front ()
644
653
: ConcatenateDnsAddresses (dns_servers);
645
- curl_easy_setopt (handle-> handle , CURLOPT_DNS_SERVERS, dns_list.c_str ());
654
+ curl_easy_setopt (curl_handle , CURLOPT_DNS_SERVERS, dns_list.c_str ());
646
655
}
647
656
#endif
648
657
649
658
if (handle->chunk ) {
650
- curl_easy_setopt (handle-> handle , CURLOPT_HTTPHEADER, handle->chunk );
659
+ curl_easy_setopt (curl_handle , CURLOPT_HTTPHEADER, handle->chunk );
651
660
}
652
661
653
662
#ifdef OLP_SDK_CURL_HAS_SUPPORT_SSL_BLOBS
654
663
if (ssl_certificates_blobs_) {
655
- curl_easy_setopt (handle-> handle , CURLOPT_SSLCERT_BLOB,
664
+ curl_easy_setopt (curl_handle , CURLOPT_SSLCERT_BLOB,
656
665
&ssl_certificates_blobs_->ssl_cert_blob );
657
- curl_easy_setopt (handle-> handle , CURLOPT_SSLKEY_BLOB,
666
+ curl_easy_setopt (curl_handle , CURLOPT_SSLKEY_BLOB,
658
667
&ssl_certificates_blobs_->ssl_key_blob );
659
- curl_easy_setopt (handle-> handle , CURLOPT_CAINFO_BLOB,
668
+ curl_easy_setopt (curl_handle , CURLOPT_CAINFO_BLOB,
660
669
&ssl_certificates_blobs_->ca_info_blob );
661
670
} else
662
671
#endif
663
672
{
664
- CURLcode error = SetCaBundlePaths (handle-> handle );
673
+ CURLcode error = SetCaBundlePaths (curl_handle );
665
674
if (CURLE_OK != error) {
666
675
OLP_SDK_LOG_ERROR (kLogTag , " Send failed - set ca bundle path failed, url="
667
676
<< request.GetUrl () << " , error=" << error
@@ -670,16 +679,16 @@ ErrorCode NetworkCurl::SendImplementation(
670
679
}
671
680
}
672
681
673
- curl_easy_setopt (handle-> handle , CURLOPT_SSL_VERIFYPEER, 1L );
674
- curl_easy_setopt (handle-> handle , CURLOPT_SSL_VERIFYHOST, 2L );
682
+ curl_easy_setopt (curl_handle , CURLOPT_SSL_VERIFYPEER, 1L );
683
+ curl_easy_setopt (curl_handle , CURLOPT_SSL_VERIFYHOST, 2L );
675
684
676
685
#ifdef OLP_SDK_USE_MD5_CERT_LOOKUP
677
- curl_easy_setopt (handle-> handle , CURLOPT_SSL_CTX_FUNCTION,
686
+ curl_easy_setopt (curl_handle , CURLOPT_SSL_CTX_FUNCTION,
678
687
&NetworkCurl::AddMd5LookupMethod);
679
- curl_easy_setopt (handle-> handle , CURLOPT_SSL_CTX_DATA, handle);
688
+ curl_easy_setopt (curl_handle , CURLOPT_SSL_CTX_DATA, handle);
680
689
#endif
681
690
682
- curl_easy_setopt (handle-> handle , CURLOPT_FOLLOWLOCATION, 1L );
691
+ curl_easy_setopt (curl_handle , CURLOPT_FOLLOWLOCATION, 1L );
683
692
684
693
// `::count` is defined on all duration types, to be on the safe side
685
694
// regarding durations on NetworkConfig. Refactoring of NetworkConfig to
@@ -690,38 +699,37 @@ ErrorCode NetworkCurl::SendImplementation(
690
699
const long timeout_ms =
691
700
CountIn<std::chrono::milliseconds>(config.GetTransferTimeoutDuration ());
692
701
693
- curl_easy_setopt (handle->handle , CURLOPT_CONNECTTIMEOUT_MS,
694
- connect_timeout_ms);
695
- curl_easy_setopt (handle->handle , CURLOPT_TIMEOUT_MS, timeout_ms);
696
- curl_easy_setopt (handle->handle , CURLOPT_WRITEFUNCTION,
702
+ curl_easy_setopt (curl_handle, CURLOPT_CONNECTTIMEOUT_MS, connect_timeout_ms);
703
+ curl_easy_setopt (curl_handle, CURLOPT_TIMEOUT_MS, timeout_ms);
704
+ curl_easy_setopt (curl_handle, CURLOPT_WRITEFUNCTION,
697
705
&NetworkCurl::RxFunction);
698
- curl_easy_setopt (handle-> handle , CURLOPT_WRITEDATA, handle);
699
- curl_easy_setopt (handle-> handle , CURLOPT_HEADERFUNCTION,
706
+ curl_easy_setopt (curl_handle , CURLOPT_WRITEDATA, handle);
707
+ curl_easy_setopt (curl_handle , CURLOPT_HEADERFUNCTION,
700
708
&NetworkCurl::HeaderFunction);
701
- curl_easy_setopt (handle-> handle , CURLOPT_HEADERDATA, handle);
702
- curl_easy_setopt (handle-> handle , CURLOPT_FAILONERROR, 0L );
709
+ curl_easy_setopt (curl_handle , CURLOPT_HEADERDATA, handle);
710
+ curl_easy_setopt (curl_handle , CURLOPT_FAILONERROR, 0L );
703
711
if (stderr_ == nullptr ) {
704
- curl_easy_setopt (handle-> handle , CURLOPT_STDERR, 0L );
712
+ curl_easy_setopt (curl_handle , CURLOPT_STDERR, 0L );
705
713
}
706
- curl_easy_setopt (handle-> handle , CURLOPT_ERRORBUFFER, handle->error_text );
714
+ curl_easy_setopt (curl_handle , CURLOPT_ERRORBUFFER, handle->error_text );
707
715
708
716
#if CURL_AT_LEAST_VERSION(7, 21, 0)
709
- curl_easy_setopt (handle-> handle , CURLOPT_ACCEPT_ENCODING, " " );
710
- curl_easy_setopt (handle-> handle , CURLOPT_TRANSFER_ENCODING, 1L );
717
+ curl_easy_setopt (curl_handle , CURLOPT_ACCEPT_ENCODING, " " );
718
+ curl_easy_setopt (curl_handle , CURLOPT_TRANSFER_ENCODING, 1L );
711
719
#endif
712
720
713
721
#if CURL_AT_LEAST_VERSION(7, 25, 0)
714
722
// Enable keep-alive (since Curl 7.25.0)
715
- curl_easy_setopt (handle-> handle , CURLOPT_TCP_KEEPALIVE, 1L );
716
- curl_easy_setopt (handle-> handle , CURLOPT_TCP_KEEPIDLE, 120L );
717
- curl_easy_setopt (handle-> handle , CURLOPT_TCP_KEEPINTVL, 60L );
723
+ curl_easy_setopt (curl_handle , CURLOPT_TCP_KEEPALIVE, 1L );
724
+ curl_easy_setopt (curl_handle , CURLOPT_TCP_KEEPIDLE, 120L );
725
+ curl_easy_setopt (curl_handle , CURLOPT_TCP_KEEPINTVL, 60L );
718
726
#endif
719
727
720
728
#if CURL_AT_LEAST_VERSION(7, 80, 0)
721
- curl_easy_setopt (handle-> handle , CURLOPT_MAXLIFETIME_CONN,
729
+ curl_easy_setopt (curl_handle , CURLOPT_MAXLIFETIME_CONN,
722
730
config.GetMaxConnectionLifetime ().count ());
723
731
#else
724
- curl_easy_setopt (handle-> handle , CURLOPT_FORBID_REUSE,
732
+ curl_easy_setopt (curl_handle , CURLOPT_FORBID_REUSE,
725
733
config.GetMaxConnectionLifetime ().count () ? 1L : 0L );
726
734
#endif
727
735
@@ -919,27 +927,35 @@ size_t NetworkCurl::HeaderFunction(char* ptr, size_t size, size_t nitems,
919
927
if (!that || !that->IsStarted () || handle->cancelled ) {
920
928
return len;
921
929
}
930
+
931
+ if (!handle->header_callback ) {
932
+ return len;
933
+ }
934
+
935
+ // Drop trailing '\r' and '\n'
922
936
size_t count = len;
923
937
while ((count > 1u ) &&
924
938
((ptr[count - 1u ] == ' \n ' ) || (ptr[count - 1u ] == ' \r ' )))
925
939
count--;
926
940
if (count == 0u ) {
927
941
return len;
928
942
}
943
+
929
944
std::string str (ptr, count);
930
945
std::size_t pos = str.find (' :' );
931
946
if (pos == std::string::npos) {
932
947
return len;
933
948
}
934
- std::string key = str.substr (0u , pos);
949
+
950
+ std::string key (str.substr (0u , pos));
935
951
std::string value;
936
952
if (pos + 2u < str.size ()) {
937
953
value = str.substr (pos + 2u );
938
954
}
939
955
940
- if (handle-> header_callback ) {
941
- handle->header_callback (key, value);
942
- }
956
+ // Callback with header key+value
957
+ handle->header_callback (key, value);
958
+
943
959
return len;
944
960
}
945
961
0 commit comments