55// Created by Marco Bambini on 12/12/24.
66//
77
8+ #define CLOUDSYNC_OMIT_CURL
9+
810#ifndef CLOUDSYNC_OMIT_NETWORK
911
1012#include <stdint.h>
11- #include "network.h"
12- #include "dbutils.h"
1313#include "utils.h"
14- #include "curl/curl.h"
14+ #include "dbutils.h"
15+ #include "network.h"
16+ #include "netword_private.h"
1517
16- #define CLOUDSYNC_ENDPOINT_PREFIX "v1/cloudsync"
17- #define CLOUDSYNC_ENDPOINT_UPLOAD "upload"
18- #define CLOUDSYNC_ENDPOINT_CHECK "check"
19- #define CLOUDSYNC_DEFAULT_ENDPOINT_PORT "443"
20- #define CLOUDSYNC_HEADER_SQLITECLOUD "Accept: sqlc/plain"
18+ #ifndef CLOUDSYNC_OMIT_CURL
19+ #include "curl/curl.h"
20+ #endif
2121
2222#define CLOUDSYNC_NETWORK_MINBUF_SIZE 512
2323#define CLOUDSYNC_SESSION_TOKEN_MAXSIZE 4096
2424
25- #define CLOUDSYNC_NETWORK_OK 1
26- #define CLOUDSYNC_NETWORK_ERROR 2
27- #define CLOUDSYNC_NETWORK_BUFFER 3
28-
2925#define MAX_QUERY_VALUE_LEN 256
3026
3127#ifndef SQLITE_CORE
@@ -34,12 +30,12 @@ SQLITE_EXTENSION_INIT3
3430
3531// MARK: -
3632
37- typedef struct {
33+ struct network_data {
3834 char site_id [UUID_STR_MAXLEN ];
3935 char * authentication ; // apikey or token
4036 char * check_endpoint ;
4137 char * upload_endpoint ;
42- } network_data ;
38+ };
4339
4440typedef struct {
4541 char * buffer ;
@@ -48,14 +44,44 @@ typedef struct {
4844 int zero_term ;
4945} network_buffer ;
5046
51- typedef struct {
52- int code ;
53- char * buffer ;
54- size_t blen ; // blen if code is SQLITE_OK, rc in case of error
55- } NETWORK_RESULT ;
47+ // MARK: -
48+
49+ void network_result_cleanup (NETWORK_RESULT * res ) {
50+ if (res -> xfree ) {
51+ res -> xfree (res -> xdata );
52+ } else if (res -> buffer ) {
53+ cloudsync_memory_free (res -> buffer );
54+ }
55+ }
56+
57+ char * network_data_get_siteid (network_data * data ) {
58+ return data -> site_id ;
59+ }
60+
61+ bool network_data_set_endpoints (network_data * data , char * auth , char * check , char * upload , bool duplicate ) {
62+ if (duplicate ) {
63+ // auth is optional
64+ char * s1 = (auth ) ? cloudsync_string_dup (auth , false) : NULL ;
65+ if (auth && !s1 ) return false;
66+ char * s2 = cloudsync_string_dup (check , false);
67+ if (!s2 ) {if (auth && s1 ) sqlite3_free (s1 ); return false;}
68+ char * s3 = cloudsync_string_dup (upload , false);
69+ if (!s3 ) {if (auth && s1 ) sqlite3_free (s1 ); sqlite3_free (s2 ); return false;}
70+
71+ auth = s1 ;
72+ check = s2 ;
73+ upload = s3 ;
74+ }
75+
76+ data -> authentication = auth ;
77+ data -> check_endpoint = check ;
78+ data -> upload_endpoint = upload ;
79+ return true;
80+ }
5681
5782// MARK: -
5883
84+ #ifndef CLOUDSYNC_OMIT_CURL
5985static bool network_buffer_check (network_buffer * data , size_t needed ) {
6086 // alloc/resize buffer
6187 if (data -> bused + needed > data -> balloc ) {
@@ -93,7 +119,7 @@ static NETWORK_RESULT network_receive_buffer (network_data *data, const char *en
93119 char errbuf [CURL_ERROR_SIZE ] = {0 };
94120
95121 CURL * curl = curl_easy_init ();
96- if (!curl ) return (NETWORK_RESULT ){CLOUDSYNC_NETWORK_ERROR , NULL , 0 };
122+ if (!curl ) return (NETWORK_RESULT ){CLOUDSYNC_NETWORK_ERROR , NULL , 0 , NULL , NULL };
97123
98124 // a buffer to store errors in
99125 curl_easy_setopt (curl , CURLOPT_ERRORBUFFER , errbuf );
@@ -141,7 +167,7 @@ static NETWORK_RESULT network_receive_buffer (network_data *data, const char *en
141167 if (headers ) curl_slist_free_all (headers );
142168
143169 // build result
144- NETWORK_RESULT result = {0 , NULL , 0 };
170+ NETWORK_RESULT result = {0 , NULL , 0 , NULL , NULL };
145171 if (rc == CURLE_OK ) {
146172 result .code = (buffer && blen ) ? CLOUDSYNC_NETWORK_BUFFER : CLOUDSYNC_NETWORK_OK ;
147173 result .buffer = buffer ;
@@ -236,6 +262,7 @@ static bool network_send_buffer (network_data *data, const char *endpoint, const
236262 if (headers ) curl_slist_free_all (headers );
237263 return result ;
238264}
265+ #endif
239266
240267int network_set_sqlite_result (sqlite3_context * context , NETWORK_RESULT * result ) {
241268 int len = 0 ;
@@ -257,8 +284,7 @@ int network_set_sqlite_result (sqlite3_context *context, NETWORK_RESULT *result)
257284 break ;
258285 }
259286
260- if (result -> buffer ) cloudsync_memory_free (result -> buffer );
261-
287+ network_result_cleanup (result );
262288 return len ;
263289}
264290
@@ -272,7 +298,7 @@ int network_download_changes (sqlite3_context *context, const char *download_url
272298 NETWORK_RESULT result = network_receive_buffer (data , download_url , NULL , false, false, NULL , NULL );
273299 if (result .code == CLOUDSYNC_NETWORK_BUFFER ) {
274300 nrows = cloudsync_payload_apply (context , result .buffer , (int )result .blen );
275- cloudsync_memory_free ( result . buffer );
301+ network_result_cleanup ( & result );
276302 } else {
277303 nrows = network_set_sqlite_result (context , & result );
278304 }
@@ -334,6 +360,7 @@ int extract_query_param(const char *query, const char *key, char *output, size_t
334360 return -3 ; // Key not found
335361}
336362
363+ #ifndef CLOUDSYNC_OMIT_CURL
337364bool network_compute_endpoints (sqlite3_context * context , network_data * data , const char * conn_string ) {
338365 // compute endpoints
339366 bool result = false;
@@ -429,13 +456,16 @@ bool network_compute_endpoints (sqlite3_context *context, network_data *data, co
429456
430457 return result ;
431458}
459+ #endif
432460
433461// MARK: -
434462
435463void cloudsync_network_init (sqlite3_context * context , int argc , sqlite3_value * * argv ) {
436464 DEBUG_FUNCTION ("cloudsync_network_init" );
437465
466+ #ifndef CLOUDSYNC_OMIT_CURL
438467 curl_global_init (CURL_GLOBAL_ALL );
468+ #endif
439469
440470 // no real network operations here
441471 // just setup the network_data struct
@@ -497,7 +527,10 @@ void cloudsync_network_cleanup (sqlite3_context *context, int argc, sqlite3_valu
497527 }
498528
499529 sqlite3_result_int (context , SQLITE_OK );
530+
531+ #ifndef CLOUDSYNC_OMIT_CURL
500532 curl_global_cleanup ();
533+ #endif
501534}
502535
503536// MARK: -
@@ -537,7 +570,7 @@ void cloudsync_network_set_apikey (sqlite3_context *context, int argc, sqlite3_v
537570void network_result_to_sqlite_error (sqlite3_context * context , NETWORK_RESULT res , const char * default_error_message ) {
538571 sqlite3_result_error (context , ((res .code == CLOUDSYNC_NETWORK_ERROR ) && (res .buffer )) ? res .buffer : default_error_message , -1 );
539572 sqlite3_result_error_code (context , ((res .code == CLOUDSYNC_NETWORK_ERROR ) && (res .blen )) ? (int )res .blen : SQLITE_ERROR );
540- if ( res . buffer ) cloudsync_memory_free ( res . buffer );
573+ network_result_cleanup ( & res );
541574}
542575
543576void cloudsync_network_send_changes (sqlite3_context * context , int argc , sqlite3_value * * argv ) {
@@ -590,7 +623,7 @@ void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3
590623 snprintf (json_payload , sizeof (json_payload ), "{\"url\":\"%s\"}" , s3_url );
591624
592625 // free res
593- if ( res . buffer ) cloudsync_memory_free ( res . buffer );
626+ network_result_cleanup ( & res );
594627
595628 // notify remote host that we succesfully uploaded changes
596629 res = network_receive_buffer (data , data -> upload_endpoint , data -> authentication , true, true, json_payload , CLOUDSYNC_HEADER_SQLITECLOUD );
@@ -609,7 +642,7 @@ void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3
609642 dbutils_settings_set_key_value (db , context , CLOUDSYNC_KEY_SEND_SEQ , buf );
610643 }
611644
612- if ( res . buffer ) cloudsync_memory_free ( res . buffer );
645+ network_result_cleanup ( & res );
613646}
614647
615648int cloudsync_network_check_internal (sqlite3_context * context , int argc , sqlite3_value * * argv ) {
@@ -633,6 +666,7 @@ int cloudsync_network_check_internal(sqlite3_context *context, int argc, sqlite3
633666 int rc = SQLITE_OK ;
634667 if (result .code == CLOUDSYNC_NETWORK_BUFFER ) {
635668 rc = network_download_changes (context , result .buffer );
669+ network_result_cleanup (& result );
636670 } else {
637671 rc = network_set_sqlite_result (context , & result );
638672 }
0 commit comments