Как отправить запрос от клиента, написанного на C, к API?

Ранее не было необходимости, но сейчас работаю над одной вещью, для которой понадобилось. Читал что-то про Curl, но, увы, гугл мне выдаёт только то, как оно делается либо через терминал (что далековато от того, что мне нужно), либо через C# (который мне вообще не нравится, да и в целом пишу я на C, а не на C#). Возможно, я как-то непонятно спросил или это язык от квадратных популярностью пользуется настолько большой, что C уже не сильно интересен кому-либо, однако мне приложение нужно написать на C (по крайней мере я хочу его написать именно на C). Сначала думал запускать дочерний процесс на условных шедевропитонах и ему подобных языках, а с помощью них писать ответ в условный server_answer.tmp.st, откуда можно было бы уже записать в переменную какую-нибудь в C, однако мне мало того, что трудно читать питон и C одновременно, так ещё и полной уверенности в том, что у меня приложение будет работать под системой с питоном, у меня тоже нет. Может, есть у кого-то идеи, что можно сделать?


Ответы (1 шт):

Автор решения: eri

Вариант на 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;
}
→ Ссылка