Skip to content

Commit e1d9434

Browse files
committed
First commit of the new refactored network code
1 parent 04d1931 commit e1d9434

File tree

3 files changed

+395
-27
lines changed

3 files changed

+395
-27
lines changed

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: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,23 @@
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

4440
typedef 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
5985
static 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

240267
int 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
337364
bool 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

435463
void 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
537570
void 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

543576
void 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

615648
int 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

Comments
 (0)