C++ Tunnel Proxy: libcurl and CPR Two Implementations
C++ libcurl and CPR libraries integrating 16Yun Crawler Proxy.
16Yun Engineering TeamMay 5, 20261 min read
libcurl
libcurl is the most widely used C/C++ HTTP client library. Configure proxies via CURLOPT_PROXY and related options.
#include <curl/curl.h>
#include <string>
#include <iostream>
size_t writeCallback(void* contents, size_t size, size_t nmemb, std::string* out) {
size_t total = size * nmemb;
out->append((char*)contents, total);
return total;
}
int main() {
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL* curl = curl_easy_init();
if (curl) {
const char* host = std::getenv("PROXY_HOST") ?: "t.16yun.cn";
const char* port = std::getenv("PROXY_PORT") ?: "31111";
const char* user = std::getenv("PROXY_USERNAME") ?: "user";
const char* pass = std::getenv("PROXY_PASSWORD") ?: "password";
curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/ip");
curl_easy_setopt(curl, CURLOPT_PROXY, host);
curl_easy_setopt(curl, CURLOPT_PROXYPORT, atoi(port));
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (std::string(user) + ":" + pass).c_str());
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15L);
std::string response;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// Proxy-Tunnel header
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Proxy-Tunnel: cpp-demo");
curl_easy_setopt(curl, CURLOPT_PROXYHEADER, headers);
CURLcode res = curl_easy_perform(curl);
if (res == CURLE_OK) {
std::cout << response << std::endl;
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}CPR
CPR is a modern C++ HTTP library built on libcurl with a cleaner API:
#include <cpr/cpr.h>
#include <iostream>
int main() {
std::string host = std::getenv("PROXY_HOST") ?: "t.16yun.cn";
std::string port = std::getenv("PROXY_PORT") ?: "31111";
std::string user = std::getenv("PROXY_USERNAME") ?: "user";
std::string pass = std::getenv("PROXY_PASSWORD") ?: "password";
cpr::Response r = cpr::Get(
cpr::Url{"https://httpbin.org/ip"},
cpr::Proxies{{"https", "http://" + host + ":" + port}},
cpr::ProxyAuthentication{{"https", cpr::EncodedAuthentication{user, pass}}},
cpr::Header{{"Proxy-Tunnel", "cpp-cpr-demo"}},
cpr::VerifySsl{false},
cpr::Timeout{15000}
);
std::cout << r.text << std::endl;
return 0;
}Comparison of Two Approaches
| Feature | libcurl | CPR |
|---|---|---|
| Dependency | libcurl-dev | libcurl + CPR header-only |
| API Style | C-style, manual management | Modern C++, chained calls |
| HTTPS | Yes | Yes |
| HTTPS Tunnel | Yes CURLOPT_PROXYHEADER | Yes cpr::Header |
| Complexity | Relatively high | Low |
Need an enterprise proxy plan?
We can tailor architecture to your target domains, concurrency, and reliability goals.