Last active
January 14, 2022 19:11
-
-
Save vinikira/8b2670224ab06627643f86cf9b2135df to your computer and use it in GitHub Desktop.
Curl request and JSON Parsing in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -xe | |
cc -Wall -Werror -std=c11 -pedantic -lcurl -ljson-c -o main main.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <curl/curl.h> | |
#include <json-c/json.h> | |
struct ResponseBuffer { | |
char *payload; | |
size_t size; | |
}; | |
int curl_callback(void *data, size_t size, size_t nmemb, void *buffer_in) { | |
size_t real_size = size * nmemb; | |
struct ResponseBuffer *p = (struct ResponseBuffer *) buffer_in; | |
char *temp = realloc(p->payload, p->size + real_size + 1); | |
if (temp == NULL) { | |
fprintf(stderr, "ERROR: Failed to expand buffer in curl_callback.\n"); | |
free(p->payload); | |
return 1; | |
} | |
p->payload = temp; | |
memcpy(&(p->payload[p->size]), data, real_size); | |
p->size += real_size; | |
p->payload[p->size] = 0; | |
return real_size; | |
} | |
CURLcode make_curl_request(char *url, struct ResponseBuffer *rb) { | |
CURL *curl; | |
struct curl_slist *headers = NULL; | |
headers = curl_slist_append(headers, "Accept: application/json"); | |
headers = curl_slist_append(headers, "charset: utf-8"); | |
curl_global_init(CURL_GLOBAL_ALL); | |
curl = curl_easy_init(); | |
if (curl == NULL) { | |
fprintf(stderr, "ERROR: Could not initialize curl.\n"); | |
return 1; | |
} | |
curl_easy_setopt(curl, CURLOPT_URL, url); | |
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); | |
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); | |
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_callback); | |
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) rb); | |
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); | |
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 15); | |
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); | |
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 1); | |
CURLcode response_code = curl_easy_perform(curl); | |
curl_easy_cleanup(curl); | |
curl_slist_free_all(headers); | |
curl_global_cleanup(); | |
return response_code; | |
} | |
int main(void) { | |
char url[] = "https://api.myip.com"; | |
struct ResponseBuffer response_buffer; | |
response_buffer.payload = (char *) calloc(1, sizeof(response_buffer.payload)); | |
if (response_buffer.payload == NULL) { | |
fprintf(stderr, "ERROR: Failed to allocate response buffer.\n"); | |
return CURLE_FAILED_INIT; | |
} | |
response_buffer.size = 0; | |
CURLcode response_code = make_curl_request(url, &response_buffer); | |
if (response_code != CURLE_OK) { | |
fprintf(stderr, "ERROR: Request failed: %s\n", curl_easy_strerror(response_code)); | |
return 1; | |
} else { | |
printf("DEBUG: Raw response: %d\n", response_code); | |
} | |
if (response_buffer.payload == NULL) { | |
fprintf(stderr, "ERROR: Failed to populate response buffer."); | |
return 1; | |
} | |
enum json_tokener_error jerr = json_tokener_success; | |
json_object *json = json_tokener_parse_verbose(response_buffer.payload, &jerr); | |
printf("DEBUG: Size - %zu\n", response_buffer.size); | |
printf("DEBUG: Payload - %s\n", response_buffer.payload); | |
printf("DEBUG: JSON parsed - %s\n", json_object_to_json_string(json)); | |
free(response_buffer.payload); | |
struct json_object *ip; | |
struct json_object *country; | |
struct json_object *cc; | |
json_object_object_get_ex(json, "ip", &ip); | |
json_object_object_get_ex(json, "country", &country); | |
json_object_object_get_ex(json, "cc", &cc); | |
printf("INFO: Result: \n"); | |
printf(" My ip: %s\n", json_object_get_string(ip)); | |
printf(" My country: %s\n", json_object_get_string(country)); | |
printf(" My country code: %s\n", json_object_get_string(cc)); | |
json_object_put(json); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment