如何从C中的CURL请求中接收JSON对象?

时间:2017-06-29 20:20:43

标签: c curl libcurl

我是用PHP做的,而且相对容易。但是,它在C中比较棘手,主要是因为cURL库比较棘手,而且C不是面向对象的。以下是我到目前为止的代码片段:

#include <curl/curl.h>

/* Make first curl call */

curl_global_init();

//initialize first curl instance
CURL *handle;
CURLcode response;
handle = curl_easy_init();

//craft url
char *url = "https://example.com/";

//set url
curl_easy_setopt(handle, CURLOPT_URL, url);

//get resonse
response = curl_easy_perform(handle);

//clean up
curl_easy_cleanup(handle);

curl应该使用get,也不应该在其中一个curlopts中指定Accept: application/json

1 个答案:

答案 0 :(得分:0)

#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    size_t len;
    void*  buf;
} Body;

typedef size_t (*WriteFunction)(void*, size_t, size_t, void*);

static size_t write_body(const void* ptr, size_t size, size_t nmemb, Body* body_ptr) {
    size_t new_len = body_ptr->len + ( size * nmemb );
    if (new_len == 0)
       return 0;

    char* new_buf = realloc(body_ptr->buf, new_len);
    if (new_buf == NULL)
       return 0;

    memcpy(((char*)body_ptr) + new_len, ptr, ( size * nmemb ));

    body_ptr->len = new_len;
    body_ptr->buf = new_buf;
}

static int write_all(int fd, void* buf, size_t remaining) {
    while (remaining > 0) {
        ssize_t written = write(STDOUT, buf, remaining);
        if (written == -1)
            return 0;

        remaning -= written;
        buf = ((char*)buf) + written;
    }

    return 1;
}

int main(void) {
    CURL* curl = NULL;
    struct curl_slist* header_list = NULL;
    Body body = { 0, NULL };
    int error = 1;

    curl = curl_easy_init();
    if (curl != NULL) {
        fprintf(stderr, "curl_easy_init() failed\n");
        goto ERROR;
    }

    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
    curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

    header_list = curl_slist_append(header_list, "Accept: application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (WriteFunction)write_body);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK)
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        goto ERROR;
    }

    long http_code;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    if (http_code < 200 || http_code >= 300) {
        fprintf(stderr, "Request not successful: HTTP error code %ld\n", http_code);
        goto ERROR;
    }

    if (body.len == 0) {
        printf("Empty response\n");
    } else {
        printf("Received %zu bytes\n", body.len);
        fflush(stdout);
        if (!write_all(STDOUT, body->buf, body->len)) {
            perror("write");
            goto ERROR;
        }
    }

    error = 0;
ERROR:
    if ( body.buf != NULL    ) free(body.buf);
    if ( header_list != NULL ) curl_slist_free_all(header_list);
    if ( curl != NULL        ) curl_easy_cleanup(curl);
    return error;
}

未经测试。