refactor
- migrate to libcurl - separate functions into files
This commit is contained in:
parent
ae53f5042c
commit
9695fe405d
@ -2,14 +2,40 @@ cmake_minimum_required(VERSION 3.5)
|
|||||||
project(YaDisk)
|
project(YaDisk)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
|
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
|
||||||
find_package(Neon REQUIRED)
|
find_package(CURL REQUIRED)
|
||||||
find_package(JsonC 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)
|
add_executable(test-app tests/app.c)
|
||||||
|
|
||||||
target_include_directories(yadisk PRIVATE ${NEON_INCLUDE_DIR} ${JSON_C_INCLUDE_DIR})
|
target_include_directories(
|
||||||
target_link_libraries(yadisk ${NEON_LIBRARIES} ${JSON_C_LIBRARIES})
|
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_include_directories(
|
||||||
target_link_libraries(test-app yadisk)
|
test-app PRIVATE
|
||||||
|
"${CMAKE_SOURCE_DIR}/src"
|
||||||
|
${NEON_INCLUDE_DIR}
|
||||||
|
${CURL_INCLUDE_DIR}
|
||||||
|
${JSON_C_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(
|
||||||
|
test-app
|
||||||
|
yadisk
|
||||||
|
)
|
@ -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)
|
|
12
src/yadisk.h
Normal file
12
src/yadisk.h
Normal file
@ -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
|
96
src/yadisk_api_internal.c
Normal file
96
src/yadisk_api_internal.c
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
//
|
||||||
|
// Created by maxim on 27.11.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <json.h>
|
||||||
|
#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;
|
||||||
|
}
|
22
src/yadisk_api_internal.h
Normal file
22
src/yadisk_api_internal.h
Normal file
@ -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
|
28
src/yadisk_get_disk.c
Normal file
28
src/yadisk_get_disk.c
Normal file
@ -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;
|
||||||
|
}
|
17
src/yadisk_get_disk.h
Normal file
17
src/yadisk_get_disk.h
Normal file
@ -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
|
11
src/yadisk_get_disk_resources.c
Normal file
11
src/yadisk_get_disk_resources.c
Normal file
@ -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);
|
||||||
|
};
|
18
src/yadisk_get_disk_resources.h
Normal file
18
src/yadisk_get_disk_resources.h
Normal file
@ -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);
|
5
src/yadisk_shared.c
Normal file
5
src/yadisk_shared.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by maxim on 27.11.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "yadisk_shared.h"
|
22
src/yadisk_shared.h
Normal file
22
src/yadisk_shared.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// Created by maxim on 27.11.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef YADISK_YADISK_SHARED_H
|
||||||
|
#define YADISK_YADISK_SHARED_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <json.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
YADISK_OK = 0,
|
||||||
|
YADISK_FAILED_PARSE_JSON = 1
|
||||||
|
} yadisk_code;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char* token;
|
||||||
|
} yadisk_api_client;
|
||||||
|
|
||||||
|
#endif //YADISK_YADISK_SHARED_H
|
@ -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;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by maxim on 26.11.23.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef YANDEX_DISK_API_H
|
|
||||||
#define YANDEX_DISK_API_H
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <ne_session.h>
|
|
||||||
#include <ne_request.h>
|
|
||||||
#include <ne_ssl.h>
|
|
||||||
|
|
||||||
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
|
|
@ -2,7 +2,7 @@
|
|||||||
// Created by maxim on 27.11.23.
|
// Created by maxim on 27.11.23.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <yandex_disk_api.h>
|
#include <yadisk.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
Loading…
Reference in New Issue
Block a user