Как отправить запрос от клиента, написанного на C, к API?
Ранее не было необходимости, но сейчас работаю над одной вещью, для которой понадобилось. Читал что-то про Curl, но, увы, гугл мне выдаёт только то, как оно делается либо через терминал (что далековато от того, что мне нужно), либо через C# (который мне вообще не нравится, да и в целом пишу я на C, а не на C#). Возможно, я как-то непонятно спросил или это язык от квадратных популярностью пользуется настолько большой, что C уже не сильно интересен кому-либо, однако мне приложение нужно написать на C (по крайней мере я хочу его написать именно на C). Сначала думал запускать дочерний процесс на условных шедевропитонах и ему подобных языках, а с помощью них писать ответ в условный server_answer.tmp.st, откуда можно было бы уже записать в переменную какую-нибудь в C, однако мне мало того, что трудно читать питон и C одновременно, так ещё и полной уверенности в том, что у меня приложение будет работать под системой с питоном, у меня тоже нет. Может, есть у кого-то идеи, что можно сделать?
Ответы (1 шт):
Вариант на libsoup с разбором json
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MyIP)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBS REQUIRED libsoup-3.0 json-glib-1.0)
add_executable(myip main.c)
target_include_directories(myip PRIVATE ${LIBS_INCLUDE_DIRS})
target_link_libraries(myip PRIVATE ${LIBS_LIBRARIES})
main.c
#include <libsoup/soup.h>
#include <json-glib/json-glib.h>
int main(int argc, char **argv)
{
SoupSession *session = soup_session_new();
SoupMessageHeaders *response_headers;
const char *content_type;
SoupMessage *msg = soup_message_new(SOUP_METHOD_GET, "https://api.ipify.org?format=json");
GError *error = NULL;
GBytes *bytes = soup_session_send_and_read(
session,
msg,
NULL, // Pass a GCancellable here if you want to cancel a download
&error);
if (error)
{
g_printerr("Failed to download: %s\n", error->message);
g_error_free(error);
g_object_unref(msg);
g_object_unref(session);
return 1;
}
response_headers = soup_message_get_response_headers(msg);
content_type = soup_message_headers_get_content_type(response_headers, NULL);
g_print("Downloaded %zu bytes of type %s\n",
g_bytes_get_size(bytes), content_type);
g_object_unref(msg);
g_object_unref(session);
ssize_t len = 0;
const gchar *data = g_bytes_get_data(bytes, &len);
JsonParser *parser = json_parser_new();
json_parser_load_from_data(parser, data, len, &error);
if (error)
{
g_printerr("Failed to parse: %s\n", error->message);
g_object_unref(parser);
g_bytes_unref(bytes);
return 1;
}
JsonNode *root = json_parser_get_root(parser);
const gchar *ip = json_object_get_string_member(json_node_get_object(root), "ip");
g_print("My IP: %s\n", ip);
g_object_unref(parser);
g_bytes_unref(bytes);
return 0;
}