2
votes

I'm trying to do HTTP POST requests with curl_easy_perform() but when code reaches

res = curl_easy_perform(curl);

it waits for EOF. When I hit Ctrl+D the code successfully finish. I'm using XCode IDE. I'm having same issue even when program runs as compiled executable from terminal.

This is my POST function with curl settings:

int BitfinexAPI::
DoPOSTrequest(const string &UrlEndPoint, const string &params, string &result)
{

    if(curl) {

        string url = APIurl + UrlEndPoint;
        string payload;
        string signature;
        getBase64(params, payload);
        getHmacSha384(secretKey, payload, signature);

        // Headers
        struct curl_slist *httpHeaders = NULL;
        httpHeaders = curl_slist_append(httpHeaders, ("X-BFX-APIKEY:" + accessKey).c_str());
        httpHeaders = curl_slist_append(httpHeaders, ("X-BFX-PAYLOAD:" + payload).c_str());
        httpHeaders = curl_slist_append(httpHeaders, ("X-BFX-SIGNATURE:" + signature).c_str());
        httpHeaders = curl_slist_append(httpHeaders, ("Expect:"));

        curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); // debug option
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_POST, 1);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, httpHeaders);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
        res = curl_easy_perform(curl);

        // libcurl internal error handling
        if (res != CURLE_OK)
        {
            cout << "Libcurl error in DoPOSTRequest(), code:\n";
            return res;
        }
        return res;

    }
    else
    {
        // curl not properly initialized curl = NULL
        return curlERR;

    }
}

And this is output from CURLOPT_VERBOSE, 0L after hitting Ctrl-D after < HTTP/1.1 100 Continue line:

*   Trying 104.16.175.181...
* TCP_NODELAY set
* Connected to api.bitfinex.com (104.16.175.181) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
* Server certificate: ssl453718.cloudflaressl.com
* Server certificate: COMODO ECC Domain Validation Secure Server CA 2
* Server certificate: COMODO ECC Certification Authority
> POST /v1/account_infos/ HTTP/1.1
Host: api.bitfinex.com
Accept: */*
X-BFX-APIKEY:NKc8RCJUDPfp1R8enTPSAi0soozYFn9MezjzmnFQJ3X
X-BFX-PAYLOAD:eyJyZXF1ZXN0IjoiL3YxL2FjY291bnRfaW5mb3MiLCJub25jZSI6IjE0ODU0NjIyNDUzNzE2MTYifQ==
X-BFX-SIGNATURE:95c396c792b59b8084b9f2523b6b7c0e948ae555e2677a07fd42e54050360a44f8f0e184db5b9fa63c4635816180ba1e
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Date: Thu, 26 Jan 2017 20:24:05 GMT
< Content-Type: application/json; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=d3d747333090623a13f70c430103686ed1485462245; expires=Fri, 26-Jan-18 20:24:05 GMT; path=/; domain=.bitfinex.com; HttpOnly
< Strict-Transport-Security: max-age=31536000
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Vary: Accept-Encoding
< ETag: W/"0ac5694d4f0d0485ba2e4640ac79cc40"
< Cache-Control: no-cache
< X-Request-Id: b5f58f5f-473f-428b-a889-74c2e7b43278
< X-Runtime: 0.029113
< Expires: Thu, 26 Jan 2017 20:24:04 GMT
< X-Frame-Options: SAMEORIGIN
< Server: cloudflare-nginx
< CF-RAY: 3276afba2efd3e20-PRG
< 
* Curl_http_done: called premature == 0
* Connection #0 to host api.bitfinex.com left intact
[{"maker_fees":"0.1","taker_fees":"0.2","fees":[{"pairs":"BTC","maker_fees":"0.1","taker_fees":"0.2"},{"pairs":"LTC","maker_fees":"0.1","taker_fees":"0.2"},{"pairs":"ETH","maker_fees":"0.1","taker_fees":"0.2"},{"pairs":"ETC","maker_fees":"0.1","taker_fees":"0.2"},{"pairs":"ZEC","maker_fees":"0.1","taker_fees":"0.2"},{"pairs":"XMR","maker_fees":"0.1","taker_fees":"0.2"}]}]
0
Program ended with exit code: 0
1

1 Answers

1
votes

Problem: The code sets CURLOPT_POST but it doesn't seem to instruct any way for libcurl to send any data in that POST request? That will make libcurl use the default internal read function, which reads from stdin...

Fix: Provide the POST data with CURLOPT_POSTFIELDS or set up the read callback with CURLOPT_READFUNCTION if you prefer that.