Skip to content

Commit 293d7e3

Browse files
committed
Network layer refactored (libcurl can now be omitted)
1 parent 6ad10b7 commit 293d7e3

File tree

4 files changed

+302
-32
lines changed

4 files changed

+302
-32
lines changed

src/cloudsync.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "sqlite3.h"
1717
#endif
1818

19-
#define CLOUDSYNC_VERSION "0.8.2"
19+
#define CLOUDSYNC_VERSION "0.8.3"
2020

2121
int sqlite3_cloudsync_init (sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);
2222

src/netword_private.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// netword_private.h
3+
// cloudsync
4+
//
5+
// Created by Marco Bambini on 23/05/25.
6+
//
7+
8+
#ifndef __CLOUDSYNC_NETWORK_PRIVATE__
9+
#define __CLOUDSYNC_NETWORK_PRIVATE__
10+
11+
#define CLOUDSYNC_ENDPOINT_PREFIX "v1/cloudsync"
12+
#define CLOUDSYNC_ENDPOINT_UPLOAD "upload"
13+
#define CLOUDSYNC_ENDPOINT_CHECK "check"
14+
#define CLOUDSYNC_DEFAULT_ENDPOINT_PORT "443"
15+
#define CLOUDSYNC_HEADER_SQLITECLOUD "Accept: sqlc/plain"
16+
17+
#define CLOUDSYNC_NETWORK_OK 1
18+
#define CLOUDSYNC_NETWORK_ERROR 2
19+
#define CLOUDSYNC_NETWORK_BUFFER 3
20+
21+
typedef struct network_data network_data;
22+
23+
typedef struct {
24+
int code; // network code: OK, ERROR, BUFFER
25+
char *buffer; // network buffer
26+
size_t blen; // blen if code is SQLITE_OK, rc in case of error
27+
void *xdata; // optional custom external data
28+
void (*xfree) (void *); // optional custom free callback
29+
} NETWORK_RESULT;
30+
31+
char *network_data_get_siteid (network_data *data);
32+
bool network_data_set_endpoints (network_data *data, char *auth, char *check, char *upload, bool duplicate);
33+
34+
bool network_compute_endpoints (sqlite3_context *context, network_data *data, const char *conn_string);
35+
bool network_send_buffer(network_data *data, const char *endpoint, const char *authentication, const void *blob, int blob_size);
36+
NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint, const char *authentication, bool zero_terminated, bool is_post_request, char *json_payload, const char *custom_header);
37+
38+
39+
#endif

src/network.c

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,24 @@
1111
#include "network.h"
1212
#include "dbutils.h"
1313
#include "utils.h"
14-
#include "curl/curl.h"
1514
#include "cloudsync_private.h"
15+
#include "netword_private.h"
16+
17+
#ifndef CLOUDSYNC_OMIT_CURL
18+
#include "curl/curl.h"
19+
#endif
1620

1721
#ifdef __ANDROID__
1822
#include "cacert.h"
1923
static size_t cacert_len = sizeof(cacert_pem) - 1;
2024
#endif
21-
22-
#define CLOUDSYNC_ENDPOINT_PREFIX "v1/cloudsync"
23-
#define CLOUDSYNC_ENDPOINT_UPLOAD "upload"
24-
#define CLOUDSYNC_ENDPOINT_CHECK "check"
25-
#define CLOUDSYNC_DEFAULT_ENDPOINT_PORT "443"
26-
#define CLOUDSYNC_HEADER_SQLITECLOUD "Accept: sqlc/plain"
27-
25+
2826
#define CLOUDSYNC_NETWORK_MINBUF_SIZE 512
2927
#define CLOUDSYNC_SESSION_TOKEN_MAXSIZE 4096
3028

3129
#define DEFAULT_SYNC_WAIT_MS 100
3230
#define DEFAULT_SYNC_MAX_RETRIES 10
33-
34-
#define CLOUDSYNC_NETWORK_OK 1
35-
#define CLOUDSYNC_NETWORK_ERROR 2
36-
#define CLOUDSYNC_NETWORK_BUFFER 3
37-
31+
3832
#define MAX_QUERY_VALUE_LEN 256
3933

4034
#ifndef SQLITE_CORE
@@ -43,12 +37,12 @@ SQLITE_EXTENSION_INIT3
4337

4438
// MARK: -
4539

46-
typedef struct {
40+
struct network_data {
4741
char site_id[UUID_STR_MAXLEN];
4842
char *authentication; // apikey or token
4943
char *check_endpoint;
5044
char *upload_endpoint;
51-
} network_data;
45+
};
5246

5347
typedef struct {
5448
char *buffer;
@@ -57,20 +51,52 @@ typedef struct {
5751
int zero_term;
5852
} network_buffer;
5953

60-
typedef struct {
61-
int code;
62-
char *buffer;
63-
size_t blen; // blen if code is SQLITE_OK, rc in case of error
64-
} NETWORK_RESULT;
65-
54+
6655
typedef struct {
6756
const char *data;
6857
size_t size;
6958
size_t read_pos;
7059
} network_read_data;
7160

61+
// MARK: -
62+
63+
void network_result_cleanup (NETWORK_RESULT *res) {
64+
if (res->xfree) {
65+
res->xfree(res->xdata);
66+
} else if (res->buffer) {
67+
cloudsync_memory_free(res->buffer);
68+
}
69+
}
70+
71+
char *network_data_get_siteid (network_data *data) {
72+
return data->site_id;
73+
}
74+
75+
bool network_data_set_endpoints (network_data *data, char *auth, char *check, char *upload, bool duplicate) {
76+
if (duplicate) {
77+
// auth is optional
78+
char *s1 = (auth) ? cloudsync_string_dup(auth, false) : NULL;
79+
if (auth && !s1) return false;
80+
char *s2 = cloudsync_string_dup(check, false);
81+
if (!s2) {if (auth && s1) sqlite3_free(s1); return false;}
82+
char *s3 = cloudsync_string_dup(upload, false);
83+
if (!s3) {if (auth && s1) sqlite3_free(s1); sqlite3_free(s2); return false;}
84+
85+
auth = s1;
86+
check = s2;
87+
upload = s3;
88+
}
89+
90+
data->authentication = auth;
91+
data->check_endpoint = check;
92+
data->upload_endpoint = upload;
93+
return true;
94+
}
95+
7296
// MARK: - Utils -
7397

98+
#ifndef CLOUDSYNC_OMIT_CURL
99+
74100
static bool network_buffer_check (network_buffer *data, size_t needed) {
75101
// alloc/resize buffer
76102
if (data->bused + needed > data->balloc) {
@@ -101,14 +127,14 @@ static size_t network_receive_callback (void *ptr, size_t size, size_t nmemb, vo
101127
return (size * nmemb);
102128
}
103129

104-
static NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint, const char *authentication, bool zero_terminated, bool is_post_request, char *json_payload, const char *custom_header) {
130+
NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint, const char *authentication, bool zero_terminated, bool is_post_request, char *json_payload, const char *custom_header) {
105131
char *buffer = NULL;
106132
size_t blen = 0;
107133
struct curl_slist* headers = NULL;
108134
char errbuf[CURL_ERROR_SIZE] = {0};
109135

110136
CURL *curl = curl_easy_init();
111-
if (!curl) return (NETWORK_RESULT){CLOUDSYNC_NETWORK_ERROR, NULL, 0};
137+
if (!curl) return (NETWORK_RESULT){CLOUDSYNC_NETWORK_ERROR, NULL, 0, NULL, NULL};
112138

113139
// a buffer to store errors in
114140
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
@@ -166,7 +192,7 @@ static NETWORK_RESULT network_receive_buffer (network_data *data, const char *en
166192
if (headers) curl_slist_free_all(headers);
167193

168194
// build result
169-
NETWORK_RESULT result = {0, NULL, 0};
195+
NETWORK_RESULT result = {0, NULL, 0, NULL, NULL};
170196
if (rc == CURLE_OK) {
171197
result.code = (buffer && blen) ? CLOUDSYNC_NETWORK_BUFFER : CLOUDSYNC_NETWORK_OK;
172198
result.buffer = buffer;
@@ -194,7 +220,7 @@ static size_t network_read_callback(char *buffer, size_t size, size_t nitems, vo
194220
return to_copy;
195221
}
196222

197-
static bool network_send_buffer (network_data *data, const char *endpoint, const char *authentication, const void *blob, int blob_size) {
223+
bool network_send_buffer (network_data *data, const char *endpoint, const char *authentication, const void *blob, int blob_size) {
198224
struct curl_slist *headers = NULL;
199225
curl_mime *mime = NULL;
200226
bool result = false;
@@ -265,6 +291,7 @@ static bool network_send_buffer (network_data *data, const char *endpoint, const
265291
if (headers) curl_slist_free_all(headers);
266292
return result;
267293
}
294+
#endif
268295

269296
int network_set_sqlite_result (sqlite3_context *context, NETWORK_RESULT *result) {
270297
int rc = 0;
@@ -287,8 +314,7 @@ int network_set_sqlite_result (sqlite3_context *context, NETWORK_RESULT *result)
287314
break;
288315
}
289316

290-
if (result->buffer) cloudsync_memory_free(result->buffer);
291-
317+
network_result_cleanup(result);
292318
return rc;
293319
}
294320

@@ -306,7 +332,7 @@ int network_download_changes (sqlite3_context *context, const char *download_url
306332
int rc = SQLITE_OK;
307333
if (result.code == CLOUDSYNC_NETWORK_BUFFER) {
308334
rc = cloudsync_payload_apply(context, result.buffer, (int)result.blen);
309-
cloudsync_memory_free(result.buffer);
335+
network_result_cleanup(&result);
310336
} else {
311337
rc = network_set_sqlite_result(context, &result);
312338
}
@@ -366,6 +392,7 @@ int network_extract_query_param(const char *query, const char *key, char *output
366392
return -3; // Key not found
367393
}
368394

395+
#ifndef CLOUDSYNC_OMIT_CURL
369396
bool network_compute_endpoints (sqlite3_context *context, network_data *data, const char *conn_string) {
370397
// compute endpoints
371398
bool result = false;
@@ -468,11 +495,12 @@ bool network_compute_endpoints (sqlite3_context *context, network_data *data, co
468495

469496
return result;
470497
}
498+
#endif
471499

472500
void network_result_to_sqlite_error (sqlite3_context *context, NETWORK_RESULT res, const char *default_error_message) {
473501
sqlite3_result_error(context, ((res.code == CLOUDSYNC_NETWORK_ERROR) && (res.buffer)) ? res.buffer : default_error_message, -1);
474502
sqlite3_result_error_code(context, ((res.code == CLOUDSYNC_NETWORK_ERROR) && (res.blen)) ? (int)res.blen : SQLITE_ERROR);
475-
if (res.buffer) cloudsync_memory_free(res.buffer);
503+
network_result_cleanup(&res);
476504
}
477505

478506
// MARK: - Init / Cleanup -
@@ -489,7 +517,9 @@ network_data *cloudsync_network_data(sqlite3_context *context) {
489517
void cloudsync_network_init (sqlite3_context *context, int argc, sqlite3_value **argv) {
490518
DEBUG_FUNCTION("cloudsync_network_init");
491519

520+
#ifndef CLOUDSYNC_OMIT_CURL
492521
curl_global_init(CURL_GLOBAL_ALL);
522+
#endif
493523

494524
// no real network operations here
495525
// just setup the network_data struct
@@ -551,7 +581,10 @@ void cloudsync_network_cleanup (sqlite3_context *context, int argc, sqlite3_valu
551581
}
552582

553583
sqlite3_result_int(context, SQLITE_OK);
584+
585+
#ifndef CLOUDSYNC_OMIT_CURL
554586
curl_global_cleanup();
587+
#endif
555588
}
556589

557590
// MARK: - Public -
@@ -638,7 +671,7 @@ void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3
638671
snprintf(json_payload, sizeof(json_payload), "{\"url\":\"%s\"}", s3_url);
639672

640673
// free res
641-
if (res.buffer) cloudsync_memory_free(res.buffer);
674+
network_result_cleanup(&res);
642675

643676
// notify remote host that we succesfully uploaded changes
644677
res = network_receive_buffer(data, data->upload_endpoint, data->authentication, true, true, json_payload, CLOUDSYNC_HEADER_SQLITECLOUD);
@@ -657,7 +690,7 @@ void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3
657690
dbutils_settings_set_key_value(db, context, CLOUDSYNC_KEY_SEND_SEQ, buf);
658691
}
659692

660-
if (res.buffer) cloudsync_memory_free(res.buffer);
693+
network_result_cleanup(&res);
661694
}
662695

663696
int cloudsync_network_check_internal(sqlite3_context *context) {

0 commit comments

Comments
 (0)