Search code examples
c++curlcmakehttpsopenssl

Getting an HTTP response status code of 0 and empty message using C++ curl library libCPR


I'm using libcpr to send a GET request.

    cpr::Response r = cpr::Get(
            cpr::Url{target.str()},
            cpr::Header{header});

For debugging, I print the response—

    std::cout << "Response Error: " << r.error.message << std::endl;
    std::cout << "Response Error Code: " << (int)r.error.code << std::endl;
    std::cout << "Response Status Code: " << r.status_code << std::endl;
    std::cout << "Response Text: " << std::endl;

—and get the following:

Response Error: 
Response Error Code: 4
Response Status Code: 0
Response Text:  

I see a lot of seemingly relevant threads online, but I feel like I've tried everything and I don't know what my particular issue is. I think someone more versed in curl, CMake, or OpenSSL might be able to spot it. So here's what I tried / know:

  1. I don't think it's a problem with my code per se—more likely a problem with my setup (dependencies, options, etc.) Because the code works for a different target, i.e. I can hit "https://api.binance.us/api" and get a 200 and response I expect. It's for the targets "https://api.exchange.coinbase.com" and "https://api.kucoin.com/api" that give me a 0 and empty response.

  2. I am able to get real responses using Postman. When I std::cout the request headers to send the same exact request using Postman, I do get a response:

    enter image description here

    (Don't worry, I've modified the values.)

  3. For Windows users there was a thread earlier this year about an issue with HTTPS requests, stemming from an issue with vcpkg. I am on macOS Big Sur (11.6.5) so this is not my issue.

  4. Just 1 month ago there was a thread that seems relevant. 17 days ago they appear to have "fixed" this issue (PR #733)—so I have pointed CMake to the latest version of libcpr, 1.8.3:

    include(FetchContent)
    FetchContent_Declare(
            cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git
            GIT_TAG db351ffbbadc6c4e9239daaa26e9aefa9f0ec82d) # 1.8.3
    FetchContent_MakeAvailable(cpr)
    target_link_libraries(myProgram PRIVATE cpr::cpr)
    

    Still no go for me.

  5. Here's what CMake outputs in case there's a hint in there I don't see:

    -- Enabled curl SSL
    -- curl version=[7.80.0]
    -- Could NOT find LibSSH2 (missing: LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR) 
    -- CA path only supported by OpenSSL, GnuTLS or mbed TLS. Set CURL_CA_PATH=none or enable one of those TLS backends.
    -- Enabled features: SSL IPv6 unixsockets libz AsynchDNS Largefile alt-svc HSTS
    -- Enabled protocols: HTTP HTTPS
    -- Enabled SSL backends: Secure Transport
    -- Configuring done
    -- Generating done
    

    Multiple threads say that versions before 7.81.0 work fine.

  6. I also tried adding the option cpr::VerifySsl{false}, but get back

    SSL peer handshake failed, the server most likely requires a client certificate to connect
    

    I kind of don't think that's the right path anyway.

Does anyone have ideas? Any other output or thing to try that might be useful?


Solution

  • Of course, it's the simplest thing that I didn't try. This warning tipped me off:

    -- Could NOT find LibSSH2 (missing: LIBSSH2_LIBRARY LIBSSH2_INCLUDE_DIR)

    I simply did a brew install libssl2 and it now works.