Skip to content

Commit 72b57c1

Browse files
committed
refactor: network_receive_buffer and improve buffer management
1 parent a4dc460 commit 72b57c1

File tree

1 file changed

+60
-76
lines changed

1 file changed

+60
-76
lines changed

src/network.c

Lines changed: 60 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -102,39 +102,10 @@ bool network_data_set_endpoints (network_data *data, char *auth, char *check, ch
102102
// MARK: - Utils -
103103

104104
#ifndef CLOUDSYNC_OMIT_CURL
105-
106-
static bool network_buffer_check (network_buffer *data, size_t needed) {
107-
// alloc/resize buffer
108-
if (data->bused + needed > data->balloc) {
109-
if (needed < CLOUDSYNC_NETWORK_MINBUF_SIZE) needed = CLOUDSYNC_NETWORK_MINBUF_SIZE;
110-
size_t balloc = (data->balloc * 2) + needed;
111-
112-
char *buffer = cloudsync_memory_realloc(data->buffer, balloc);
113-
if (!buffer) return false;
114-
115-
data->buffer = buffer;
116-
data->balloc = balloc;
117-
}
118-
119-
return true;
120-
}
121-
122-
static size_t network_receive_callback (void *ptr, size_t size, size_t nmemb, void *xdata) {
123-
network_buffer *data = (network_buffer *)xdata;
124-
125-
size_t ptr_size = (size*nmemb);
126-
if (data->zero_term) ptr_size += 1;
127-
128-
if (network_buffer_check(data, ptr_size) == false) return -1;
129-
memcpy(data->buffer+data->bused, ptr, size*nmemb);
130-
data->bused += size*nmemb;
131-
if (data->zero_term) data->buffer[data->bused] = 0;
132-
133-
return (size * nmemb);
134-
}
135-
136105
#ifdef SQLITE_WASM_EXTRA_INIT
137106
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) {
107+
char *buffer = NULL;
108+
size_t blen = 0;
138109

139110
emscripten_fetch_attr_t attr;
140111
emscripten_fetch_attr_init(&attr);
@@ -145,11 +116,8 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
145116
} else {
146117
strcpy(attr.requestMethod, "GET");
147118
}
148-
attr.onerror = NULL; // No progress callback
149-
attr.onsuccess = NULL; // No success callback
150-
attr.onprogress = NULL; // No progress callback
151119
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_REPLACE;
152-
120+
153121
// Prepare header array (alternating key, value, NULL-terminated)
154122
const char *headers[11];
155123
int h = 0;
@@ -183,59 +151,44 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
183151
headers[h++] = "Content-Type";
184152
headers[h++] = "application/json";
185153
}
186-
187-
// Accept (always)
188-
headers[h++] = "Accept";
189-
headers[h++] = "application/octet-stream";
154+
190155
headers[h] = 0;
191156
attr.requestHeaders = headers;
192157

193158
// Body
194159
if (json_payload) {
195160
attr.requestData = json_payload;
196161
attr.requestDataSize = strlen(json_payload);
197-
} else if (is_post_request) {
198-
attr.requestData = "";
199-
attr.requestDataSize = 0;
200162
}
201-
//endpoint = "https://echo.free.beeceptor.com";
163+
202164
emscripten_fetch_t *fetch = emscripten_fetch(&attr, endpoint); // Blocks here until the operation is complete.
203165
NETWORK_RESULT result = {0, NULL, 0, NULL, NULL};
204-
fprintf(stderr, "network_receive_buffer: %s %s\n", attr.requestMethod, endpoint);
205-
fprintf(stderr, "emscripten_fetch returned, fetch pointer: %p\n", fetch);
206-
fprintf(stderr, "network_receive_buffer: status %u, numBytes %zu\n", fetch->status, fetch->numBytes);
207-
fprintf(stderr, "network_receive_buffer: statusText %s\n", fetch->statusText ? fetch->statusText : "NULL");
208-
fprintf(stderr, "network_receive_buffer: readyState %u\n", fetch->readyState);
209-
fprintf(stderr, "network_receive_buffer: data pointer %p\n", fetch->data);
210-
211-
if (fetch->readyState != 4) {
212-
fprintf(stderr, "ERROR: fetch not completed, readyState=%u\n", fetch->readyState);
213-
result.code = CLOUDSYNC_NETWORK_ERROR;
214-
result.buffer = strdup("Network request did not complete");
215-
emscripten_fetch_close(fetch);
216-
if (custom_key) free(custom_key);
217-
return result;
166+
167+
if(fetch->readyState == 4){
168+
buffer = fetch->data;
169+
blen = fetch->totalBytes;
218170
}
219171

220-
if (fetch->status == 200) {
221-
fprintf(stderr, "status is 200 OK\n");
222-
result.code = (fetch->numBytes > 0) ? CLOUDSYNC_NETWORK_BUFFER : CLOUDSYNC_NETWORK_OK;
223-
result.buffer = (char *)malloc(fetch->numBytes + 1);
224-
if (result.buffer && fetch->numBytes > 0) {
225-
memcpy(result.buffer, fetch->data, fetch->numBytes);
226-
result.buffer[fetch->numBytes] = 0;
227-
result.blen = fetch->numBytes;
228-
} else if (result.buffer) {
229-
result.buffer[0] = 0;
230-
result.blen = 0;
231-
}
172+
if (fetch->status >= 200 && fetch->status < 300) {
173+
174+
if (blen > 0 && buffer) {
175+
char *buf = (char*)malloc(blen + 1);
176+
if (buf) {
177+
memcpy(buf, buffer, blen);
178+
buf[blen] = 0;
179+
result.code = CLOUDSYNC_NETWORK_BUFFER;
180+
result.buffer = buf;
181+
result.blen = blen;
182+
result.xfree = free;
183+
} else result.code = CLOUDSYNC_NETWORK_ERROR;
184+
} else result.code = CLOUDSYNC_NETWORK_OK;
232185
} else {
233186
result.code = CLOUDSYNC_NETWORK_ERROR;
234-
if (fetch->statusText && fetch->statusText[0])
187+
if (fetch->statusText && fetch->statusText[0]) {
235188
result.buffer = strdup(fetch->statusText);
236-
else
237-
result.buffer = strdup("Network error");
238-
result.blen = 0;
189+
}
190+
result.blen = sizeof(fetch->statusText);
191+
result.xfree = free;
239192
}
240193

241194
// cleanup
@@ -245,6 +198,37 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
245198
return result;
246199
}
247200
#else
201+
202+
static bool network_buffer_check (network_buffer *data, size_t needed) {
203+
// alloc/resize buffer
204+
if (data->bused + needed > data->balloc) {
205+
if (needed < CLOUDSYNC_NETWORK_MINBUF_SIZE) needed = CLOUDSYNC_NETWORK_MINBUF_SIZE;
206+
size_t balloc = data->balloc + needed;
207+
208+
char *buffer = cloudsync_memory_realloc(data->buffer, balloc);
209+
if (!buffer) return false;
210+
211+
data->buffer = buffer;
212+
data->balloc = balloc;
213+
}
214+
215+
return true;
216+
}
217+
218+
static size_t network_receive_callback (void *ptr, size_t size, size_t nmemb, void *xdata) {
219+
network_buffer *data = (network_buffer *)xdata;
220+
221+
size_t ptr_size = (size*nmemb);
222+
if (data->zero_term) ptr_size += 1;
223+
224+
if (network_buffer_check(data, ptr_size) == false) return -1;
225+
memcpy(data->buffer+data->bused, ptr, size*nmemb);
226+
data->bused += size*nmemb;
227+
if (data->zero_term) data->buffer[data->bused] = 0;
228+
229+
return (size * nmemb);
230+
}
231+
248232
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) {
249233
char *buffer = NULL;
250234
size_t blen = 0;
@@ -286,7 +270,7 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
286270
network_buffer netdata = {NULL, 0, 0, (zero_terminated) ? 1 : 0};
287271
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &netdata);
288272
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, network_receive_callback);
289-
273+
290274
// add optional JSON payload (implies setting CURLOPT_POST to 1)
291275
// or set the CURLOPT_POST option
292276
if (json_payload) {
@@ -346,7 +330,7 @@ bool network_send_buffer(network_data *data, const char *endpoint, const char *a
346330
emscripten_fetch_attr_t attr;
347331
emscripten_fetch_attr_init(&attr);
348332
strcpy(attr.requestMethod, "PUT");
349-
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS;
333+
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_SYNCHRONOUS | EMSCRIPTEN_FETCH_REPLACE;
350334

351335
// Prepare headers (alternating key, value, NULL-terminated)
352336
// Max 3 headers: Accept, (optional Auth), Content-Type
@@ -370,7 +354,7 @@ bool network_send_buffer(network_data *data, const char *endpoint, const char *a
370354
attr.requestDataSize = blob_size;
371355

372356
emscripten_fetch_t *fetch = emscripten_fetch(&attr, endpoint); // Blocks here until the operation is complete.
373-
if (fetch->status == 200) result = true;
357+
if (fetch->status >= 200 && fetch->status < 300) result = true;
374358

375359
emscripten_fetch_close(fetch);
376360

0 commit comments

Comments
 (0)