From 9695fe405d7399a6a43fda9d843d35cee9d86e74 Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Mon, 27 Nov 2023 19:50:27 +0300 Subject: [PATCH] refactor - migrate to libcurl - separate functions into files --- CMakeLists.txt | 38 ++++++++-- cmake/modules/FindNeon.cmake | 19 ----- src/yadisk.h | 12 ++++ src/yadisk_api_internal.c | 96 +++++++++++++++++++++++++ src/yadisk_api_internal.h | 22 ++++++ src/yadisk_get_disk.c | 28 ++++++++ src/yadisk_get_disk.h | 17 +++++ src/yadisk_get_disk_resources.c | 11 +++ src/yadisk_get_disk_resources.h | 18 +++++ src/yadisk_shared.c | 5 ++ src/yadisk_shared.h | 22 ++++++ src/yandex_disk_api.c | 122 -------------------------------- src/yandex_disk_api.h | 26 ------- tests/app.c | 2 +- 14 files changed, 264 insertions(+), 174 deletions(-) delete mode 100644 cmake/modules/FindNeon.cmake create mode 100644 src/yadisk.h create mode 100644 src/yadisk_api_internal.c create mode 100644 src/yadisk_api_internal.h create mode 100644 src/yadisk_get_disk.c create mode 100644 src/yadisk_get_disk.h create mode 100644 src/yadisk_get_disk_resources.c create mode 100644 src/yadisk_get_disk_resources.h create mode 100644 src/yadisk_shared.c create mode 100644 src/yadisk_shared.h delete mode 100644 src/yandex_disk_api.c delete mode 100644 src/yandex_disk_api.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 14d92c5..5a7928e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,14 +2,40 @@ cmake_minimum_required(VERSION 3.5) project(YaDisk) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) -find_package(Neon REQUIRED) +find_package(CURL REQUIRED) find_package(JsonC REQUIRED) -add_library(yadisk src/yandex_disk_api.c) +add_library(yadisk + src/yadisk_get_disk_resources.c + src/yadisk_api_internal.c + src/yadisk_api_internal.h + src/yadisk_get_disk_resources.h + src/yadisk.h + src/yadisk_get_disk.c + src/yadisk_get_disk.h + src/yadisk_shared.c + src/yadisk_shared.h +) add_executable(test-app tests/app.c) -target_include_directories(yadisk PRIVATE ${NEON_INCLUDE_DIR} ${JSON_C_INCLUDE_DIR}) -target_link_libraries(yadisk ${NEON_LIBRARIES} ${JSON_C_LIBRARIES}) +target_include_directories( + yadisk PRIVATE + ${CURL_INCLUDE_DIR} + ${JSON_C_INCLUDE_DIR} +) +target_link_libraries(yadisk + ${CURL_LIBRARIES} + ${JSON_C_LIBRARIES} +) -target_include_directories(test-app PRIVATE "${CMAKE_SOURCE_DIR}/src" ${NEON_INCLUDE_DIR} ${JSON_C_INCLUDE_DIR}) -target_link_libraries(test-app yadisk) \ No newline at end of file +target_include_directories( + test-app PRIVATE + "${CMAKE_SOURCE_DIR}/src" + ${NEON_INCLUDE_DIR} + ${CURL_INCLUDE_DIR} + ${JSON_C_INCLUDE_DIR} +) +target_link_libraries( + test-app + yadisk +) \ No newline at end of file diff --git a/cmake/modules/FindNeon.cmake b/cmake/modules/FindNeon.cmake deleted file mode 100644 index 53f9cfd..0000000 --- a/cmake/modules/FindNeon.cmake +++ /dev/null @@ -1,19 +0,0 @@ -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE(PkgConfig) -PKG_CHECK_MODULES(PKG_NEON neon) - -FIND_PATH(NEON_INCLUDE_DIR ne_request.h - PATHS - ${PKG_NEON_INCLUDE_DIRS} - /usr/include - /usr/local/include - PATH_SUFFIXES neon -) - -FIND_LIBRARY(NEON_LIBRARIES neon - ${PKG_NEON_LIBRARY_DIRS} - /usr/lib - /usr/local/lib -) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Neon DEFAULT_MSG NEON_LIBRARIES NEON_INCLUDE_DIR) \ No newline at end of file diff --git a/src/yadisk.h b/src/yadisk.h new file mode 100644 index 0000000..9ebdfaf --- /dev/null +++ b/src/yadisk.h @@ -0,0 +1,12 @@ +// +// Created by maxim on 27.11.23. +// + +#ifndef YADISK_YADISK_H +#define YADISK_YADISK_H + +#include "yadisk_shared.h" +#include "yadisk_get_disk.h" +#include "yadisk_get_disk_resources.h" + +#endif //YADISK_YADISK_H diff --git a/src/yadisk_api_internal.c b/src/yadisk_api_internal.c new file mode 100644 index 0000000..1574f77 --- /dev/null +++ b/src/yadisk_api_internal.c @@ -0,0 +1,96 @@ +// +// Created by maxim on 27.11.23. +// + +#include +#include +#include +#include +#include "yadisk_shared.h" +#include "yadisk_api_internal.h" + +struct memory { + char *response; + size_t size; +}; + +// Callback function for writing response data +static size_t write_callback(void *contents, size_t size, size_t nmemb, struct memory *mem) { + size_t realsize = size * nmemb; + char *ptr = realloc(mem->response, mem->size + realsize + 1); + if(!ptr) { + // out of memory + printf("not enough memory (realloc returned NULL)\n"); + return 0; + } + + mem->response = ptr; + memcpy(&(mem->response[mem->size]), contents, realsize); + mem->size += realsize; + mem->response[mem->size] = 0; + + return realsize; +} + +// Function to make an HTTP request using libcurl +int api_http_request( + yadisk_api_client *client, + const char* method, + const char* path, + query_param *params, + size_t num_params, + char** output + ) { + CURL *curl; + CURLcode res; + struct memory chunk = {0}; + + curl_global_init(CURL_GLOBAL_ALL); + curl = curl_easy_init(); + + if(curl) { + char url[256]; + snprintf(url, sizeof(url), "%s%s", YANDEX_DISK_API_HOST, path); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); + + // Set the HTTP method + if (strcmp(method, "GET") == 0) { + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); + } else if (strcmp(method, "POST") == 0) { + curl_easy_setopt(curl, CURLOPT_POST, 1L); + } else if (strcmp(method, "DELETE") == 0) { + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); + } else if (strcmp(method, "PATCH") == 0) { + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH"); + } + + // Set the authorization header + char auth_header[256]; + snprintf(auth_header, sizeof(auth_header), "Authorization: OAuth %s", client->token); + struct curl_slist *headers = NULL; + headers = curl_slist_append(headers, auth_header); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + // Perform the request + res = curl_easy_perform(curl); + if(res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + free(chunk.response); + curl_easy_cleanup(curl); + curl_global_cleanup(); + return -1; + } else { + *output = strdup(chunk.response); + } + + // Clean up + curl_slist_free_all(headers); + free(chunk.response); + curl_easy_cleanup(curl); + } + + curl_global_cleanup(); + return 0; +} \ No newline at end of file diff --git a/src/yadisk_api_internal.h b/src/yadisk_api_internal.h new file mode 100644 index 0000000..c1542a1 --- /dev/null +++ b/src/yadisk_api_internal.h @@ -0,0 +1,22 @@ +// +// Created by maxim on 27.11.23. +// + +#ifndef YADISK_YADISK_API_INTERNAL_H +#define YADISK_YADISK_API_INTERNAL_H + +#define YANDEX_DISK_API_HOST "https://cloud-api.yandex.net" + +typedef struct { + const char *key; + const char *value; +} query_param; + +int api_http_request(yadisk_api_client *client, + const char *method, + const char *path, + query_param *params, + size_t num_params, + char **output); + +#endif //YADISK_YADISK_API_INTERNAL_H diff --git a/src/yadisk_get_disk.c b/src/yadisk_get_disk.c new file mode 100644 index 0000000..0999587 --- /dev/null +++ b/src/yadisk_get_disk.c @@ -0,0 +1,28 @@ +// +// Created by maxim on 27.11.23. +// + +#include "yadisk_get_disk.h" +#include "yadisk_api_internal.h" + +yadisk_code yadisk_get_disk(yadisk_api_client *client, yadisk_disk_info* info) { + char* output = NULL; + int error = api_http_request(client, "GET", "/v1/disk", NULL, 0, &output); + json_object* root = json_tokener_parse(output); + if (error) { + json_object_put(root); + return YADISK_FAILED_PARSE_JSON; + } + + json_object* total_space = NULL; + if (!json_object_object_get_ex(root, "total_space", &total_space)) { + // printf("Key total_space doesn't exists!"); + return YADISK_FAILED_PARSE_JSON; + } + info->total_space = json_object_get_uint64(total_space); + json_object_put(total_space); + + json_object_put(root); + free(output); + return YADISK_OK; +} \ No newline at end of file diff --git a/src/yadisk_get_disk.h b/src/yadisk_get_disk.h new file mode 100644 index 0000000..276149e --- /dev/null +++ b/src/yadisk_get_disk.h @@ -0,0 +1,17 @@ +// +// Created by maxim on 27.11.23. +// + +#ifndef YADISK_YADISK_GET_DISK_H +#define YADISK_YADISK_GET_DISK_H + +#include "yadisk_shared.h" + +typedef struct yadisk_disk_info +{ + unsigned long total_space; +} yadisk_disk_info; + +yadisk_code yadisk_get_disk(yadisk_api_client *client, yadisk_disk_info* info); + +#endif //YADISK_YADISK_GET_DISK_H diff --git a/src/yadisk_get_disk_resources.c b/src/yadisk_get_disk_resources.c new file mode 100644 index 0000000..3077f71 --- /dev/null +++ b/src/yadisk_get_disk_resources.c @@ -0,0 +1,11 @@ +// +// Created by maxim on 27.11.23. +// +#include "yadisk_get_disk_resources.h" +#include "yadisk_api_internal.h" + +yadisk_code +yadisk_get_disk_resources(yadisk_api_client *client, const char *path) { + char *output; + int error = api_http_request(client, "GET", "/v1/disk", NULL, 0, &output); +}; \ No newline at end of file diff --git a/src/yadisk_get_disk_resources.h b/src/yadisk_get_disk_resources.h new file mode 100644 index 0000000..c70e49d --- /dev/null +++ b/src/yadisk_get_disk_resources.h @@ -0,0 +1,18 @@ +// +// Created by maxim on 27.11.23. +// +#include "yadisk_shared.h" + +typedef struct { +} yadisk_resource_embedded; + +typedef struct +{ + const char* path; + const char* name; + const char* resource_id; + const char* type; + const yadisk_resource_embedded* _embedded; +} yadisk_resource_info; + +yadisk_code yadisk_get_disk_resources(yadisk_api_client *client, const char *path); \ No newline at end of file diff --git a/src/yadisk_shared.c b/src/yadisk_shared.c new file mode 100644 index 0000000..1f6bb04 --- /dev/null +++ b/src/yadisk_shared.c @@ -0,0 +1,5 @@ +// +// Created by maxim on 27.11.23. +// + +#include "yadisk_shared.h" diff --git a/src/yadisk_shared.h b/src/yadisk_shared.h new file mode 100644 index 0000000..c06ed41 --- /dev/null +++ b/src/yadisk_shared.h @@ -0,0 +1,22 @@ +// +// Created by maxim on 27.11.23. +// + +#ifndef YADISK_YADISK_SHARED_H +#define YADISK_YADISK_SHARED_H + +#include +#include +#include + +typedef enum { + YADISK_OK = 0, + YADISK_FAILED_PARSE_JSON = 1 +} yadisk_code; + +typedef struct +{ + char* token; +} yadisk_api_client; + +#endif //YADISK_YADISK_SHARED_H diff --git a/src/yandex_disk_api.c b/src/yandex_disk_api.c deleted file mode 100644 index 5e982ac..0000000 --- a/src/yandex_disk_api.c +++ /dev/null @@ -1,122 +0,0 @@ -// -// Created by maxim on 26.11.23. -// - -#include "yandex_disk_api.h" -#include "json.h" - -#define YANDEX_DISK_API_HOST "cloud-api.yandex.net" - -static int ssl_verify_callback(void *userdata, int failures, const ne_ssl_certificate *cert); -static int api_http_request( - yadisk_api_client *client, - const char* method, - const char* path, - char** output - ); - -void yadisk_get_disk(yadisk_api_client *client, yadisk_disk_info* info) { - char* output = NULL; - int error = api_http_request(client, "GET", "/v1/disk", &output); - json_object* root = json_tokener_parse(output); - - if (error) { - json_object_put(root); - return; - } - - json_object* total_space = NULL; - if (!json_object_object_get_ex(root, "total_space", &total_space)) { - printf("Key total_space doesn't exists!"); - } - info->total_space = json_object_get_uint64(total_space); - json_object_put(total_space); - - json_object_put(root); - free(output); -} - -void yadisk_delete_disk_resources(yadisk_api_client *client) { - char* output = NULL; - int result = api_http_request(client, "DELETE", "/v1/disk/resource", &output); - - if (!result) { - // error - } - - free(output); -} - -static int ssl_verify_callback(void *userdata, int failures, const ne_ssl_certificate *cert) { - if (failures & NE_SSL_UNTRUSTED) { - return 0; - } - return 1; -}; - -static void -set_api_auth_header( - ne_request *req, - yadisk_api_client* client -) { - size_t str_size = 6 + strlen(client->token) + 1; - char *str = malloc(sizeof(char) * str_size); - snprintf(str, str_size, "OAuth %s", client->token); - ne_add_request_header(req, "Authorization", str); -} - -static int -api_http_request( - yadisk_api_client* client, - const char* method, - const char* path, - char** output - ) -{ - ne_session *sess; - ne_request *req; - sess = ne_session_create("https", YANDEX_DISK_API_HOST, 443); - ne_ssl_set_verify(sess, ssl_verify_callback, NULL); - - req = ne_request_create(sess, method, path); - - set_api_auth_header(req, client); - - char* result = malloc(1); - size_t currentSize = 1; // Текущий размер буфера result - - do { - int stat = ne_begin_request(req); - const ne_status* status = ne_get_status(req); - - if (stat != NE_OK) { - if (!status->code) { - return -1; - } - return -1; - } - - if (status->code != 200) { - return -2; - } - - char buffer[1024]; - ssize_t bytes; // Количество прочитанных байт - - while ((bytes = ne_read_response_block(req, buffer, 1024)) > 0) { - currentSize += bytes; - result = realloc(result, currentSize); - strncat(result, buffer, bytes); - } - } while (ne_end_request(req)); - - ne_request_destroy(req); - ne_session_destroy(sess); - ne_sock_exit(); - - *output = malloc(currentSize * sizeof(char)); - strcpy(*output, result); - free(result); - - return 0; -} \ No newline at end of file diff --git a/src/yandex_disk_api.h b/src/yandex_disk_api.h deleted file mode 100644 index add9624..0000000 --- a/src/yandex_disk_api.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Created by maxim on 26.11.23. -// - -#ifndef YANDEX_DISK_API_H -#define YANDEX_DISK_API_H - -#include -#include -#include -#include - -typedef struct yadisk_api_client -{ - char* token; -} yadisk_api_client; - -typedef struct yadisk_disk_info -{ - unsigned long total_space; -} yadisk_disk_info; - -void yadisk_get_disk(yadisk_api_client* client, yadisk_disk_info* info); -void yadisk_delete_disk_resources(yadisk_api_client *client); - -#endif //YANDEX_DISK_API_H diff --git a/tests/app.c b/tests/app.c index 034695b..c7e3f7a 100644 --- a/tests/app.c +++ b/tests/app.c @@ -2,7 +2,7 @@ // Created by maxim on 27.11.23. // -#include +#include #include int main() {