Skip to content

Commit d90f172

Browse files
committed
Improved internal_socket_forward_read
1 parent 8458ae9 commit d90f172

1 file changed

Lines changed: 41 additions & 33 deletions

File tree

C/sqcloud.c

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,7 +1350,9 @@ static bool internal_socket_forward_read (SQCloudConnection *connection, bool (*
13501350
uint32_t cstart = 0;
13511351
uint32_t tread = 0;
13521352
uint32_t clen = 0;
1353+
char type = 0;
13531354

1355+
ssize_t nread = 0;
13541356
char *buffer = sbuffer;
13551357
char *original = buffer;
13561358
int fd = connection->fd;
@@ -1361,56 +1363,62 @@ static bool internal_socket_forward_read (SQCloudConnection *connection, bool (*
13611363
while (1) {
13621364
// perform read operation
13631365
#ifndef SQLITECLOUD_DISABLE_TLS
1364-
ssize_t nread = (tls) ? tls_read(tls, buffer, blen) : readsocket(fd, buffer, blen);
1366+
nread = (tls) ? tls_read(tls, buffer, blen) : readsocket(fd, buffer, blen);
13651367
if ((tls) && (nread == TLS_WANT_POLLIN || nread == TLS_WANT_POLLOUT)) continue;
13661368
#else
1367-
ssize_t nread = readsocket(fd, buffer, blen);
1369+
nread = readsocket(fd, buffer, blen);
13681370
#endif
1371+
if (nread == -1 && errno == EINTR) continue;
13691372

13701373
// sanity check read
1371-
if (nread < 0) {
1372-
const char *msg = "";
1373-
#ifndef SQLITECLOUD_DISABLE_TLS
1374-
if (tls) msg = tls_error(tls);
1375-
#endif
1376-
1377-
internal_set_error(connection, INTERNAL_ERRCODE_NETWORK, "An error occurred while reading data: %s (%s).", strerror(errno), msg);
1378-
goto abort_read;
1379-
}
1380-
1381-
if (nread == 0) {
1382-
const char *msg = "";
1383-
#ifndef SQLITECLOUD_DISABLE_TLS
1384-
if (tls) msg = tls_error(tls);
1385-
#endif
1386-
1387-
internal_set_error(connection, INTERNAL_ERRCODE_NETWORK, "Unexpected EOF found while reading data: %s (%s).", strerror(errno), msg);
1388-
goto abort_read;
1389-
}
1374+
if (nread <= 0) goto abort_read;
13901375

13911376
// forward read to callback
13921377
bool result = forward_cb(buffer, nread, xdata, xdata2);
13931378
if (!result) goto abort_read;
13941379

1395-
// update internal counter
1396-
tread += (uint32_t)nread;
1380+
// read original type
1381+
if (type == 0) type = buffer[0];
13971382

1398-
// determine command length
1399-
if (clen == 0) {
1400-
clen = internal_parse_number (&original[1], tread-1, &cstart);
1383+
if (type != CMD_ROWSET_CHUNK) {
1384+
// update internal counter
1385+
tread += (uint32_t)nread;
1386+
1387+
// determine command length
1388+
if (clen == 0) {
1389+
clen = internal_parse_number (&original[1], tread-1, &cstart);
1390+
1391+
// handle special cases
1392+
if ((original[0] == CMD_INT) || (original[0] == CMD_FLOAT) || (original[0] == CMD_NULL)) clen = 0;
1393+
else if (clen == 0) continue;
1394+
}
1395+
1396+
// check if read is complete
1397+
if (clen + cstart + 1 == tread) break;
1398+
} else {
1399+
const char *end_of_chunk = "/6 0 0 0 ";
1400+
size_t end_of_chunk_len = 9;
14011401

1402-
// handle special cases
1403-
if ((original[0] == CMD_INT) || (original[0] == CMD_FLOAT) || (original[0] == CMD_NULL)) clen = 0;
1404-
else if (clen == 0) continue;
1402+
if (nread >= end_of_chunk_len) {
1403+
if (strncmp(buffer + nread - end_of_chunk_len, end_of_chunk, end_of_chunk_len) == 0) break;
1404+
} else {
1405+
// there is an extremely rare possibility that the end of chuck was split by the TCP driver
1406+
// in that case we would have no way to determine the end of the rowset chunk
1407+
;
1408+
}
14051409
}
1406-
1407-
// check if read is complete
1408-
if (clen + cstart + 1 == tread) break;
14091410
}
14101411

14111412
return true;
14121413

1413-
abort_read:
1414+
abort_read: {
1415+
const char *msg = "";
1416+
const char *format = (nread == 0) ? "Unexpected EOF found while reading data: %s (%s)." : "An error occurred while reading data: %s (%s).";
1417+
#ifndef SQLITECLOUD_DISABLE_TLS
1418+
if (tls) msg = tls_error(tls);
1419+
#endif
1420+
internal_set_error(connection, INTERNAL_ERRCODE_NETWORK, format, strerror(errno), msg);
1421+
}
14141422
return false;
14151423
}
14161424

0 commit comments

Comments
 (0)