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

FeaturelibcurlCPR
Dependencylibcurl-devlibcurl + CPR header-only
API StyleC-style, manual managementModern C++, chained calls
HTTPSYesYes
HTTPS TunnelYes CURLOPT_PROXYHEADERYes cpr::Header
ComplexityRelatively highLow

Need an enterprise proxy plan?

We can tailor architecture to your target domains, concurrency, and reliability goals.