Repository navigation
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #851 +/- ##
==========================================
+ Coverage 91.54% 91.72% +0.17%
==========================================
Files 235 235
Lines 28787 28928 +141
==========================================
+ Hits 26353 26533 +180
+ Misses 2434 2395 -39 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| remoteShell_connection_print(connection, RS_ERROR); | ||
| remoteShell_connection_print(connection, RS_PROMPT); | ||
| if (len > 0) { | ||
| if (len < COMMAND_BUFF_SIZE) { |
There was a problem hiding this comment.
Strictly speaking, we cannot assume a single TCP read returns the whole request body. This remark also applies to
The correct way is illustrated by the following official example
#define RECV_BUF_SIZE 1 << 20
size_t read_data(struct mg_connection* conn,
uint8_t* buff,
size_t buff_len) {
size_t read_len = 0;
while (read_len < buff_len) {
size_t sz_to_read = std::min<size_t>(RECV_BUF_SIZE, buff_len - read_len);
int this_read = mg_read(conn, buff + read_len, sz_to_read);
if (this_read < 0) {
std::cerr << "[error] Failed to read data" << std::endl;
break;
} else {
read_len += size_t(this_read);
if (this_read > 0) {
std::cout << "[debug] Received " << this_read << " more bytes" << std::endl;
}
}
}
return read_len;
}There was a problem hiding this comment.
updated the read for remote shell and applied to same pattern to rsa and http admin
PengZheng
left a comment
There was a problem hiding this comment.
Nice improvement for our networking code.
The HTTP code is good enough except for its zero return handling.
The TCP part is more difficult to deal with raw socket API.
| } else { | ||
| while (totalBytesRead < length) { | ||
| int read = mg_read(connection, buffer + totalBytesRead, length - totalBytesRead); | ||
| if (read <= 0) { |
There was a problem hiding this comment.
read == 0 usually means EOF, rather than an error.
The function mg_read() receives data over an existing connection. The data is handled as binary and is stored in a buffer whose address has been provided as a parameter. The function returns the number of read bytes when successful, the value 0 when the connection has been closed by peer and a negative value when no more data could be read from the connection.
| @@ -528,41 +528,54 @@ static int remoteServiceAdmin_callback(struct mg_connection *conn) { | |||
| if (export != NULL) { | |||
| uint64_t datalength = request_info->content_length; | |||
There was a problem hiding this comment.
According to official documentation:
|
content_length|long long| The content length of the request body. This value can be -1 if no content length was provided. The request may still have body data, but the server cannot determine the length until all data has arrived (e.g. when the client closes the connection, or the final chunk of a chunked request has been received). |
If every request body is required to have content_length, then we need to check against -1.
Do we need to check against a reasonable upper bound to avoid allocating too much memory?
| } else { //error | ||
| remoteShell_connection_print(connection, RS_ERROR); | ||
| remoteShell_connection_print(connection, RS_PROMPT); | ||
| len = recv(fd, buff + used, COMMAND_BUFF_SIZE - 1 - used, 0); |
There was a problem hiding this comment.
This is still not robust enough. A common error breaking this is EINTR, which requires retry.
Note EINTR is not the only such status code, EAGAIN/EWOULDBLOCK to name a few.
We also need to take platform difference (macOS and Linux) into account.
Improve remote shell loop by
recvreturn and then logging result and exiting loop if needed.