Compare commits
	
		
			2 Commits
		
	
	
		
			9aafd0f238
			...
			54fa7bb7d0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 54fa7bb7d0 | |||
| f69b73187e | 
@@ -10,50 +10,96 @@
 | 
			
		||||
#include "yadisk_api_internal.h"
 | 
			
		||||
 | 
			
		||||
struct memory {
 | 
			
		||||
    char *response;
 | 
			
		||||
    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) {
 | 
			
		||||
struct data {
 | 
			
		||||
    char trace_ascii; /* 1 or 0 */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static size_t cb(void* data, size_t size, size_t nmemb, void* clientp)
 | 
			
		||||
{
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
    struct memory* mem = (struct memory*)clientp;
 | 
			
		||||
 | 
			
		||||
    char* ptr = realloc(mem->response, mem->size + realsize + 1);
 | 
			
		||||
    if (ptr == NULL)
 | 
			
		||||
        return 0;  /* out of memory! */
 | 
			
		||||
 | 
			
		||||
    mem->response = ptr;
 | 
			
		||||
    memcpy(&(mem->response[mem->size]), contents, realsize);
 | 
			
		||||
    memcpy(&(mem->response[mem->size]), data, realsize);
 | 
			
		||||
    mem->size += realsize;
 | 
			
		||||
    mem->response[mem->size] = 0;
 | 
			
		||||
 | 
			
		||||
    return realsize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* build_query_string(query_param* params, size_t num_params)
 | 
			
		||||
{
 | 
			
		||||
    CURL* curl = curl_easy_init();
 | 
			
		||||
    if (!curl) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char* query = NULL;
 | 
			
		||||
    size_t query_len = 0;
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < num_params; ++i) {
 | 
			
		||||
        char* encoded_key = curl_easy_escape(curl, params[i].key, 0);
 | 
			
		||||
        char* encoded_value = curl_easy_escape(curl, params[i].value, 0);
 | 
			
		||||
 | 
			
		||||
        // Calculate additional space needed: key=value& (including null terminator)
 | 
			
		||||
        size_t additional_len = strlen(encoded_key) + strlen(encoded_value) + 2;
 | 
			
		||||
        if (i < num_params - 1) {
 | 
			
		||||
            additional_len++; // For '&'
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        query = realloc(query, query_len + additional_len);
 | 
			
		||||
        sprintf(query + query_len, "%s=%s", encoded_key, encoded_value);
 | 
			
		||||
        query_len += additional_len - 1; // Minus null terminator
 | 
			
		||||
 | 
			
		||||
        if (i < num_params - 1) {
 | 
			
		||||
            strcat(query, "&");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        curl_free(encoded_key);
 | 
			
		||||
        curl_free(encoded_value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    curl_easy_cleanup(curl);
 | 
			
		||||
    return query;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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;
 | 
			
		||||
    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);
 | 
			
		||||
    if (curl) {
 | 
			
		||||
        char url[512];
 | 
			
		||||
        if (num_params) {
 | 
			
		||||
            char* query_string = build_query_string(params, num_params);
 | 
			
		||||
            snprintf(url, sizeof(url), "%s%s?%s", YANDEX_DISK_API_HOST, path, query_string);
 | 
			
		||||
            free(query_string);
 | 
			
		||||
        } else {
 | 
			
		||||
            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);
 | 
			
		||||
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
 | 
			
		||||
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
 | 
			
		||||
 | 
			
		||||
        // Set the HTTP method
 | 
			
		||||
        if (strcmp(method, "GET") == 0) {
 | 
			
		||||
@@ -69,17 +115,16 @@ int api_http_request(
 | 
			
		||||
        // Set the authorization header
 | 
			
		||||
        char auth_header[256];
 | 
			
		||||
        snprintf(auth_header, sizeof(auth_header), "Authorization: OAuth %s", client->token);
 | 
			
		||||
        struct curl_slist *headers = NULL;
 | 
			
		||||
        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) {
 | 
			
		||||
        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);
 | 
			
		||||
@@ -91,6 +136,5 @@ int api_http_request(
 | 
			
		||||
        curl_easy_cleanup(curl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    curl_global_cleanup();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,15 +8,41 @@
 | 
			
		||||
#define YANDEX_DISK_API_HOST "https://cloud-api.yandex.net"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    const char *key;
 | 
			
		||||
    const char *value;
 | 
			
		||||
    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,
 | 
			
		||||
int api_http_request(yadisk_api_client* client,
 | 
			
		||||
                     const char* method,
 | 
			
		||||
                     const char* path,
 | 
			
		||||
                     query_param* params,
 | 
			
		||||
                     size_t num_params,
 | 
			
		||||
                     char **output);
 | 
			
		||||
                     char** output);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define THROW_PARSE_JSON_ERROR { \
 | 
			
		||||
        return YADISK_FAILED_PARSE_JSON; \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define __DANGER_GET_JSON_OBJECT(root, key)          \
 | 
			
		||||
    json_object* obj = NULL;                         \
 | 
			
		||||
    if (!json_object_object_get_ex(root, key, &obj)){\
 | 
			
		||||
        json_object_put(root);                       \
 | 
			
		||||
        THROW_PARSE_JSON_ERROR                       \
 | 
			
		||||
    }                                                \
 | 
			
		||||
 | 
			
		||||
#define GET_JSON_STRING(root, key, v) {              \
 | 
			
		||||
        __DANGER_GET_JSON_OBJECT(root, key)              \
 | 
			
		||||
        *v = json_object_get_string(obj);                \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#define GET_JSON_UINT64(root, key, v) {              \
 | 
			
		||||
        __DANGER_GET_JSON_OBJECT(root, key)              \
 | 
			
		||||
        *v = json_object_get_uint64(obj);                \
 | 
			
		||||
    }
 | 
			
		||||
#define GET_JSON_BOOL(root, key, v) {                \
 | 
			
		||||
        __DANGER_GET_JSON_OBJECT(root, key)              \
 | 
			
		||||
        *v = json_object_get_boolean(obj);               \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif //YADISK_YADISK_API_INTERNAL_H
 | 
			
		||||
 
 | 
			
		||||
@@ -9,21 +9,21 @@ 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;
 | 
			
		||||
        return YADISK_FAILED_HTTP_REQUEST;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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* root = json_tokener_parse(output);
 | 
			
		||||
    free(output);
 | 
			
		||||
 | 
			
		||||
    GET_JSON_UINT64(root, "total_space", &(info->total_space));
 | 
			
		||||
    GET_JSON_UINT64(root, "trash_size", &(info->trash_size));
 | 
			
		||||
    GET_JSON_UINT64(root, "used_space", &(info->used_space));
 | 
			
		||||
    GET_JSON_STRING(root, "reg_time", &(info->reg_time));
 | 
			
		||||
    GET_JSON_BOOL(root, "is_paid", &(info->is_paid));
 | 
			
		||||
 | 
			
		||||
    json_object_put(root);
 | 
			
		||||
    free(output);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return YADISK_OK;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,10 @@
 | 
			
		||||
 | 
			
		||||
typedef struct yadisk_disk_info {
 | 
			
		||||
    unsigned long total_space;
 | 
			
		||||
    unsigned long trash_size;
 | 
			
		||||
    unsigned long used_space;
 | 
			
		||||
    int is_paid;
 | 
			
		||||
    const char* reg_time;
 | 
			
		||||
} yadisk_disk_info;
 | 
			
		||||
 | 
			
		||||
yadisk_code yadisk_get_disk(yadisk_api_client* client, yadisk_disk_info* info);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,27 @@
 | 
			
		||||
#include "yadisk_api_internal.h"
 | 
			
		||||
 | 
			
		||||
yadisk_code
 | 
			
		||||
yadisk_get_disk_resources(yadisk_api_client* client, const char* path)
 | 
			
		||||
yadisk_get_disk_resources(
 | 
			
		||||
    yadisk_api_client* client, const char* path, yadisk_resource_info* info
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    char* output;
 | 
			
		||||
    int error = api_http_request(client, "GET", "/v1/disk", NULL, 0, &output);
 | 
			
		||||
    char* output = NULL;
 | 
			
		||||
    query_param params[] = {
 | 
			
		||||
        {"path", path},
 | 
			
		||||
    };
 | 
			
		||||
    int error = api_http_request(client, "GET", "/v1/disk/resources", params, 1, &output);
 | 
			
		||||
    if (error) {
 | 
			
		||||
        return YADISK_FAILED_HTTP_REQUEST;
 | 
			
		||||
    }
 | 
			
		||||
    json_object* root = json_tokener_parse(output);
 | 
			
		||||
    free(output);
 | 
			
		||||
    GET_JSON_STRING(root, "path", &(info->path));
 | 
			
		||||
    GET_JSON_STRING(root, "name", &(info->name));
 | 
			
		||||
    GET_JSON_STRING(root, "resource_id", &(info->resource_id));
 | 
			
		||||
    GET_JSON_STRING(root, "type", &(info->type));
 | 
			
		||||
    GET_JSON_STRING(root, "created", &(info->created));
 | 
			
		||||
    GET_JSON_STRING(root, "modified", &(info->modified));
 | 
			
		||||
 | 
			
		||||
    json_object_put(root);
 | 
			
		||||
    return YADISK_OK;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,34 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by maxim on 27.11.23.
 | 
			
		||||
//
 | 
			
		||||
#ifndef YADISK_GET_DISK_RESOURCES_H_INCLUDED
 | 
			
		||||
#define YADISK_GET_DISK_RESOURCES_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include "yadisk_shared.h"
 | 
			
		||||
 | 
			
		||||
#define YADISK_RESOURCE_ITEM_PROPERTIES \
 | 
			
		||||
    const char* path; \
 | 
			
		||||
    const char* name; \
 | 
			
		||||
    const char* resource_id; \
 | 
			
		||||
    const char* type; \
 | 
			
		||||
    const char* created; \
 | 
			
		||||
    const char* modified;
 | 
			
		||||
 | 
			
		||||
struct yadisk_resource_item {
 | 
			
		||||
    YADISK_RESOURCE_ITEM_PROPERTIES
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    unsigned long limit;
 | 
			
		||||
    unsigned long offset;
 | 
			
		||||
    unsigned long total;
 | 
			
		||||
} yadisk_resource_embedded;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    const char* path;
 | 
			
		||||
    const char* name;
 | 
			
		||||
    const char* resource_id;
 | 
			
		||||
    const char* type;
 | 
			
		||||
typedef struct {
 | 
			
		||||
    YADISK_RESOURCE_ITEM_PROPERTIES
 | 
			
		||||
    const yadisk_resource_embedded* _embedded;
 | 
			
		||||
} yadisk_resource_info;
 | 
			
		||||
 | 
			
		||||
yadisk_code yadisk_get_disk_resources(yadisk_api_client *client, const char *path);
 | 
			
		||||
yadisk_code yadisk_get_disk_resources(yadisk_api_client* client, const char* path, yadisk_resource_info* resource);
 | 
			
		||||
 | 
			
		||||
#endif // YADISK_GET_DISK_RESOURCES_H_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -3,3 +3,13 @@
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "yadisk_shared.h"
 | 
			
		||||
 | 
			
		||||
int yadisk_init()
 | 
			
		||||
{
 | 
			
		||||
    return curl_global_init(CURL_GLOBAL_ALL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void yadisk_cleanup()
 | 
			
		||||
{
 | 
			
		||||
    curl_global_cleanup();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,11 +11,15 @@
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
    YADISK_OK = 0,
 | 
			
		||||
    YADISK_FAILED_PARSE_JSON = 1
 | 
			
		||||
    YADISK_FAILED_PARSE_JSON = 1,
 | 
			
		||||
    YADISK_FAILED_HTTP_REQUEST = 2
 | 
			
		||||
} yadisk_code;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    char* token;
 | 
			
		||||
} yadisk_api_client;
 | 
			
		||||
 | 
			
		||||
int yadisk_init();
 | 
			
		||||
void yadisk_cleanup();
 | 
			
		||||
 | 
			
		||||
#endif //YADISK_YADISK_SHARED_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								tests/app.c
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								tests/app.c
									
									
									
									
									
								
							@@ -5,21 +5,40 @@
 | 
			
		||||
#include <yadisk.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
int main() {
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    char token[1024];
 | 
			
		||||
 | 
			
		||||
    printf("Enter OAuth token: ");
 | 
			
		||||
    fgets(token, sizeof(token), stdin);
 | 
			
		||||
 | 
			
		||||
    yadisk_api_client* client = &(yadisk_api_client){
 | 
			
		||||
            .token = token
 | 
			
		||||
    yadisk_init();
 | 
			
		||||
 | 
			
		||||
    yadisk_api_client* client = &(yadisk_api_client) {
 | 
			
		||||
        .token = token
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    yadisk_disk_info yadisk_disk_info;
 | 
			
		||||
 | 
			
		||||
    yadisk_get_disk(client, &yadisk_disk_info);
 | 
			
		||||
 | 
			
		||||
    printf("Total disk size: %lu", yadisk_disk_info.total_space);
 | 
			
		||||
    printf("Total disk size: %lu\n", yadisk_disk_info.total_space);
 | 
			
		||||
    printf("Trash size: %lu\n", yadisk_disk_info.trash_size);
 | 
			
		||||
    printf("Used space: %lu\n", yadisk_disk_info.used_space);
 | 
			
		||||
    printf("Registration time: %s\n", yadisk_disk_info.reg_time);
 | 
			
		||||
    printf("Is paid: %s\n", yadisk_disk_info.is_paid ? "Yes" : "No");
 | 
			
		||||
 | 
			
		||||
    printf("=================\n");
 | 
			
		||||
 | 
			
		||||
    yadisk_resource_info resource;
 | 
			
		||||
    yadisk_get_disk_resources(client, "/", &resource);
 | 
			
		||||
    printf("Path: %s\n", resource.path);
 | 
			
		||||
    printf("Name: %s\n", resource.name);
 | 
			
		||||
    printf("Type: %s\n", resource.type);
 | 
			
		||||
    printf("Created: %s\n", resource.created);
 | 
			
		||||
    printf("Modified: %s\n", resource.modified);
 | 
			
		||||
    printf("ResourceID: %s\n", resource.resource_id);
 | 
			
		||||
 | 
			
		||||
    yadisk_cleanup();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user