Skip to content

Commit f1c7b47

Browse files
uhertleinUlrich Hertlein
andauthored
Skip header processing if no 'header_callback' (#1450)
- 'HeaderFunction' is called for every line of the header - if no 'header_callback' is given by the user, we can skip all processing altogether - uses CURLINFO_SIZE_DOWNLOAD_T with off_t for >= 7.55.0 - uses local 'curl_handle' instead of 'handle->handle' Resolves: OLPEDGE-2865 Signed-off-by: Ulrich Hertlein <ulrich.hertlein@here.com> Co-authored-by: Ulrich Hertlein <ulrich.hertlein@here.com>
1 parent 3ed1708 commit f1c7b47

File tree

1 file changed

+70
-54
lines changed

1 file changed

+70
-54
lines changed

olp-cpp-sdk-core/src/http/curl/NetworkCurl.cpp

Lines changed: 70 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)