@@ -219,12 +219,21 @@ void GetTrafficData(CURL* handle, uint64_t& upload_bytes,
219219 download_bytes += headers_size;
220220 }
221221
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
222230 double length_downloaded;
223231 if (curl_easy_getinfo (handle, CURLINFO_SIZE_DOWNLOAD, &length_downloaded) ==
224232 CURLE_OK &&
225233 length_downloaded > 0.0 ) {
226234 download_bytes += length_downloaded;
227235 }
236+ #endif
228237
229238 long length_upload;
230239 if (curl_easy_getinfo (handle, CURLINFO_REQUEST_SIZE, &length_upload) ==
@@ -564,40 +573,42 @@ ErrorCode NetworkCurl::SendImplementation(
564573 handle->chunk = curl_slist_append (handle->chunk , sstrm.str ().c_str ());
565574 }
566575
576+ CURL* curl_handle = handle->handle ;
577+
567578 if (verbose_) {
568- curl_easy_setopt (handle-> handle , CURLOPT_VERBOSE, 1L );
579+ curl_easy_setopt (curl_handle , CURLOPT_VERBOSE, 1L );
569580 if (stderr_ != nullptr ) {
570- curl_easy_setopt (handle-> handle , CURLOPT_STDERR, stderr_);
581+ curl_easy_setopt (curl_handle , CURLOPT_STDERR, stderr_);
571582 }
572583 } else {
573- curl_easy_setopt (handle-> handle , CURLOPT_VERBOSE, 0L );
584+ curl_easy_setopt (curl_handle , CURLOPT_VERBOSE, 0L );
574585 }
575586
576- curl_easy_setopt (handle-> handle , CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
587+ curl_easy_setopt (curl_handle , CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
577588
578589 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 ());
580591 auto verb = request.GetVerb ();
581592 if (verb == NetworkRequest::HttpVerb::POST ||
582593 verb == NetworkRequest::HttpVerb::PUT ||
583594 verb == NetworkRequest::HttpVerb::PATCH) {
584595 if (verb == NetworkRequest::HttpVerb::POST) {
585- curl_easy_setopt (handle-> handle , CURLOPT_POST, 1L );
596+ curl_easy_setopt (curl_handle , CURLOPT_POST, 1L );
586597 } else if (verb == NetworkRequest::HttpVerb::PUT) {
587598 // 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" );
589600 } else if (verb == NetworkRequest::HttpVerb::PATCH) {
590- curl_easy_setopt (handle-> handle , CURLOPT_CUSTOMREQUEST, " PATCH" );
601+ curl_easy_setopt (curl_handle , CURLOPT_CUSTOMREQUEST, " PATCH" );
591602 }
592603 } else if (verb == NetworkRequest::HttpVerb::DEL) {
593- curl_easy_setopt (handle-> handle , CURLOPT_CUSTOMREQUEST, " DELETE" );
604+ curl_easy_setopt (curl_handle , CURLOPT_CUSTOMREQUEST, " DELETE" );
594605 } else if (verb == NetworkRequest::HttpVerb::OPTIONS) {
595- curl_easy_setopt (handle-> handle , CURLOPT_CUSTOMREQUEST, " OPTIONS" );
606+ curl_easy_setopt (curl_handle , CURLOPT_CUSTOMREQUEST, " OPTIONS" );
596607 } else { // GET or HEAD
597- curl_easy_setopt (handle-> handle , CURLOPT_POST, 0L );
608+ curl_easy_setopt (curl_handle , CURLOPT_POST, 0L );
598609
599610 if (verb == NetworkRequest::HttpVerb::HEAD) {
600- curl_easy_setopt (handle-> handle , CURLOPT_NOBODY, 1L );
611+ curl_easy_setopt (curl_handle , CURLOPT_NOBODY, 1L );
601612 }
602613 }
603614
@@ -606,32 +617,30 @@ ErrorCode NetworkCurl::SendImplementation(
606617 // These can also be used to add body data to a CURLOPT_CUSTOMREQUEST
607618 // such as delete.
608619 if (handle->body && !handle->body ->empty ()) {
609- curl_easy_setopt (handle-> handle , CURLOPT_POSTFIELDSIZE,
620+ curl_easy_setopt (curl_handle , CURLOPT_POSTFIELDSIZE,
610621 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 ());
613623 } else {
614624 // 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 );
616626 }
617627 }
618628
619629 const auto & proxy = config.GetProxySettings ();
620630 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 ());
624633 const auto proxy_type = proxy.GetType ();
625634 if (proxy_type != NetworkProxySettings::Type::HTTP) {
626- curl_easy_setopt (handle-> handle , CURLOPT_PROXYTYPE,
635+ curl_easy_setopt (curl_handle , CURLOPT_PROXYTYPE,
627636 ToCurlProxyType (proxy_type));
628637 }
629638
630639 // We expect that both fields are empty or filled
631640 if (!proxy.GetUsername ().empty () && !proxy.GetPassword ().empty ()) {
632- curl_easy_setopt (handle-> handle , CURLOPT_PROXYUSERNAME,
641+ curl_easy_setopt (curl_handle , CURLOPT_PROXYUSERNAME,
633642 proxy.GetUsername ().c_str ());
634- curl_easy_setopt (handle-> handle , CURLOPT_PROXYPASSWORD,
643+ curl_easy_setopt (curl_handle , CURLOPT_PROXYPASSWORD,
635644 proxy.GetPassword ().c_str ());
636645 }
637646 }
@@ -642,26 +651,26 @@ ErrorCode NetworkCurl::SendImplementation(
642651 const std::string& dns_list = dns_servers.size () == 1
643652 ? dns_servers.front ()
644653 : 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 ());
646655 }
647656#endif
648657
649658 if (handle->chunk ) {
650- curl_easy_setopt (handle-> handle , CURLOPT_HTTPHEADER, handle->chunk );
659+ curl_easy_setopt (curl_handle , CURLOPT_HTTPHEADER, handle->chunk );
651660 }
652661
653662#ifdef OLP_SDK_CURL_HAS_SUPPORT_SSL_BLOBS
654663 if (ssl_certificates_blobs_) {
655- curl_easy_setopt (handle-> handle , CURLOPT_SSLCERT_BLOB,
664+ curl_easy_setopt (curl_handle , CURLOPT_SSLCERT_BLOB,
656665 &ssl_certificates_blobs_->ssl_cert_blob );
657- curl_easy_setopt (handle-> handle , CURLOPT_SSLKEY_BLOB,
666+ curl_easy_setopt (curl_handle , CURLOPT_SSLKEY_BLOB,
658667 &ssl_certificates_blobs_->ssl_key_blob );
659- curl_easy_setopt (handle-> handle , CURLOPT_CAINFO_BLOB,
668+ curl_easy_setopt (curl_handle , CURLOPT_CAINFO_BLOB,
660669 &ssl_certificates_blobs_->ca_info_blob );
661670 } else
662671#endif
663672 {
664- CURLcode error = SetCaBundlePaths (handle-> handle );
673+ CURLcode error = SetCaBundlePaths (curl_handle );
665674 if (CURLE_OK != error) {
666675 OLP_SDK_LOG_ERROR (kLogTag , " Send failed - set ca bundle path failed, url="
667676 << request.GetUrl () << " , error=" << error
@@ -670,16 +679,16 @@ ErrorCode NetworkCurl::SendImplementation(
670679 }
671680 }
672681
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 );
675684
676685#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,
678687 &NetworkCurl::AddMd5LookupMethod);
679- curl_easy_setopt (handle-> handle , CURLOPT_SSL_CTX_DATA, handle);
688+ curl_easy_setopt (curl_handle , CURLOPT_SSL_CTX_DATA, handle);
680689#endif
681690
682- curl_easy_setopt (handle-> handle , CURLOPT_FOLLOWLOCATION, 1L );
691+ curl_easy_setopt (curl_handle , CURLOPT_FOLLOWLOCATION, 1L );
683692
684693 // `::count` is defined on all duration types, to be on the safe side
685694 // regarding durations on NetworkConfig. Refactoring of NetworkConfig to
@@ -690,38 +699,37 @@ ErrorCode NetworkCurl::SendImplementation(
690699 const long timeout_ms =
691700 CountIn<std::chrono::milliseconds>(config.GetTransferTimeoutDuration ());
692701
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,
697705 &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,
700708 &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 );
703711 if (stderr_ == nullptr ) {
704- curl_easy_setopt (handle-> handle , CURLOPT_STDERR, 0L );
712+ curl_easy_setopt (curl_handle , CURLOPT_STDERR, 0L );
705713 }
706- curl_easy_setopt (handle-> handle , CURLOPT_ERRORBUFFER, handle->error_text );
714+ curl_easy_setopt (curl_handle , CURLOPT_ERRORBUFFER, handle->error_text );
707715
708716#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 );
711719#endif
712720
713721#if CURL_AT_LEAST_VERSION(7, 25, 0)
714722 // 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 );
718726#endif
719727
720728#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,
722730 config.GetMaxConnectionLifetime ().count ());
723731#else
724- curl_easy_setopt (handle-> handle , CURLOPT_FORBID_REUSE,
732+ curl_easy_setopt (curl_handle , CURLOPT_FORBID_REUSE,
725733 config.GetMaxConnectionLifetime ().count () ? 1L : 0L );
726734#endif
727735
@@ -919,27 +927,35 @@ size_t NetworkCurl::HeaderFunction(char* ptr, size_t size, size_t nitems,
919927 if (!that || !that->IsStarted () || handle->cancelled ) {
920928 return len;
921929 }
930+
931+ if (!handle->header_callback ) {
932+ return len;
933+ }
934+
935+ // Drop trailing '\r' and '\n'
922936 size_t count = len;
923937 while ((count > 1u ) &&
924938 ((ptr[count - 1u ] == ' \n ' ) || (ptr[count - 1u ] == ' \r ' )))
925939 count--;
926940 if (count == 0u ) {
927941 return len;
928942 }
943+
929944 std::string str (ptr, count);
930945 std::size_t pos = str.find (' :' );
931946 if (pos == std::string::npos) {
932947 return len;
933948 }
934- std::string key = str.substr (0u , pos);
949+
950+ std::string key (str.substr (0u , pos));
935951 std::string value;
936952 if (pos + 2u < str.size ()) {
937953 value = str.substr (pos + 2u );
938954 }
939955
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+
943959 return len;
944960}
945961
0 commit comments