mirror of
https://github.com/outbackdingo/parodus.git
synced 2026-01-28 10:20:04 +00:00
nopoll:
* [fix] Several updates to detect when __nopoll_conn_get_ssl_context fails to report a valid SSL_CTX (fixed updated test_19). * [fix] Updated header read handling to support all cases when a splitted/broken header is received. Added regression tests test_31, test_32, test_33, test_34 and test_35 to simulate and support different scenarios where part of the header is received and then the rest...
This commit is contained in:
@@ -602,6 +602,7 @@ nopoll_bool __nopoll_conn_set_ssl_client_options (noPollCtx * ctx, noPollConn *
|
||||
} /* end if */
|
||||
|
||||
/* enable default verification paths */
|
||||
/* printf ("conn = %p, conn->ssl_ctx = %p\n", conn, conn->ssl_ctx); */
|
||||
if (SSL_CTX_set_default_verify_paths (conn->ssl_ctx) != 1) {
|
||||
nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Unable to configure default verification paths, SSL_CTX_set_default_verify_paths () failed");
|
||||
return nopoll_false;
|
||||
@@ -774,10 +775,15 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx,
|
||||
if (enable_tls) {
|
||||
/* found TLS connection request, enable it */
|
||||
conn->ssl_ctx = __nopoll_conn_get_ssl_context (ctx, conn, options, nopoll_true);
|
||||
if (conn->ssl_ctx == NULL) {
|
||||
nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Unable to enable TLS, internal __nopoll_conn_get_ssl_context (ctx=%p, conn=%p, options=%p, nopoll_true) failed",
|
||||
ctx, conn, options);
|
||||
goto fail_ssl_connection;
|
||||
} /* end if */
|
||||
|
||||
/* check for client side SSL configuration */
|
||||
if (! __nopoll_conn_set_ssl_client_options (ctx, conn, options)) {
|
||||
nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Unable to configure additional SSL options, unable to continue",
|
||||
nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Unable to configure additional SSL options, unable to continue, conn->ssl_ctx=%p, conn->ssl=%p",
|
||||
conn->ssl_ctx, conn->ssl);
|
||||
goto fail_ssl_connection;
|
||||
} /* end if */
|
||||
@@ -2885,11 +2891,21 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn)
|
||||
unsigned integer */
|
||||
bytes = __nopoll_conn_receive (conn, buffer + 2, 2);
|
||||
if (bytes != 2) {
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "Failed to get next 2 bytes to read header from the wire, failed to received content, shutting down id=%d the connection, errno=%d (%s)", conn->id, errno, strerror (errno));
|
||||
if (errno == NOPOLL_EWOULDBLOCK) {
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "Failed to get next 2 bytes to read header from the wire, but received=%d, failed to received content, shutting down id=%d the connection, errno=%d (%s)",
|
||||
bytes, conn->id, errno, strerror (errno));
|
||||
if (errno == NOPOLL_EWOULDBLOCK || errno == 0) {
|
||||
/* connection is not ready at this point */
|
||||
conn->previous_msg = msg;
|
||||
conn->read_pending_header = nopoll_true;
|
||||
|
||||
/* check amount of bytes to reuse them */
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "Detected broken WebSocket peer sending header content using different frames, trying to save and resume later");
|
||||
if (bytes > 0) {
|
||||
/* ok, store content read into the pending buffer for next call */
|
||||
memcpy (conn->pending_buf + conn->pending_buf_bytes, buffer + 2, bytes);
|
||||
conn->pending_buf_bytes += bytes;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2902,6 +2918,8 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn)
|
||||
header_size += bytes;
|
||||
|
||||
msg->payload_size = nopoll_get_16bit (buffer + 2);
|
||||
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Received (%d) bytes in header (size %d) for payload size indication, which finally is: %d", bytes, header_size,(int) msg->payload_size);
|
||||
|
||||
} else if (msg->payload_size == 127) {
|
||||
#if defined(NOPOLL_64BIT_PLATFORM)
|
||||
@@ -3054,7 +3072,7 @@ read_payload:
|
||||
|
||||
/* flag that this message doesn't have FIN = 0 because
|
||||
* we wasn't able to read it entirely */
|
||||
msg->has_fin = 0;
|
||||
/* msg->has_fin = 0; */
|
||||
} /* end if */
|
||||
|
||||
/* flag the message was being a fragment according to previous flag */
|
||||
@@ -3844,21 +3862,22 @@ int nopoll_conn_send_frame (noPollConn * conn, nopoll_bool fin, nopoll_bool mask
|
||||
desp = 0;
|
||||
tries = 0;
|
||||
|
||||
/***** BEGIN INTERNAL debug code for test_30 : nopoll-regression-client.c ******/
|
||||
if (conn->__force_stop_after_header) {
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "Sending broken header and implement a pause on purpose...");
|
||||
/***** BEGIN INTERNAL debug code for test_30, test_31, test_32, test_33, test_34, test_35 : nopoll-regression-client.c ******/
|
||||
if ((conn->__force_stop_after_header > 0) && (conn->__force_stop_after_header < (length + header_size))) {
|
||||
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "Sending broken header (just %d bytes) and implement a pause on purpose...", conn->__force_stop_after_header);
|
||||
|
||||
/* send just 2 bytes for the header and then implement a very long pause */
|
||||
bytes_written = conn->send (conn, send_buffer, 2);
|
||||
desp = 2;
|
||||
if (bytes_written != 2) {
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "Requested to write 2 bytes for the header but %d were written",
|
||||
bytes_written);
|
||||
bytes_written = conn->send (conn, send_buffer, conn->__force_stop_after_header);
|
||||
desp = conn->__force_stop_after_header;
|
||||
if (bytes_written != conn->__force_stop_after_header) {
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "Requested to write %d bytes for the header but %d were written",
|
||||
conn->__force_stop_after_header, bytes_written);
|
||||
desp = 0;
|
||||
} /* end if */
|
||||
|
||||
/* sleep after header ... */
|
||||
nopoll_sleep (5000); /* 5 seconds */
|
||||
nopoll_sleep (5000000); /* 5 seconds */
|
||||
|
||||
} /* end if */
|
||||
/****** END INTERNAL debug code for test_30 : nopoll-regression-client.c ******/
|
||||
|
||||
@@ -2415,7 +2415,7 @@ nopoll_bool test_29 (void) {
|
||||
relases ****/
|
||||
#include <nopoll_private.h>
|
||||
|
||||
nopoll_bool test_30 (void) {
|
||||
nopoll_bool test_30_common_header_stop (const char * label, int bytes_to_send_before_stop) {
|
||||
|
||||
noPollConn * conn;
|
||||
noPollCtx * ctx;
|
||||
@@ -2434,16 +2434,19 @@ nopoll_bool test_30 (void) {
|
||||
return nopoll_false;
|
||||
} /* end if */
|
||||
|
||||
printf ("Test 30: waiting until connection is ready..\n");
|
||||
printf ("Test %s: waiting until connection is ready..\n", label);
|
||||
/* wait until it is connected */
|
||||
nopoll_conn_wait_until_connection_ready (conn, 5);
|
||||
printf ("Test 30: ok..\n");
|
||||
printf ("Test %s: ok..\n", label);
|
||||
|
||||
/* send a message to request connection close with a particular message */
|
||||
conn->__force_stop_after_header = nopoll_true;
|
||||
conn->__force_stop_after_header = bytes_to_send_before_stop;
|
||||
|
||||
printf ("Test 30: sending first message..\n");
|
||||
length = strlen (msg);
|
||||
|
||||
printf ("Test %s: sending first message (of %d bytes, sending broken header of %d, pausing then, and then sending the rest..)\n",
|
||||
label, length, bytes_to_send_before_stop);
|
||||
|
||||
if (nopoll_conn_send_text (conn, msg, length) != length) {
|
||||
printf ("ERROR: failed to send message..");
|
||||
return nopoll_false;
|
||||
@@ -2455,7 +2458,7 @@ nopoll_bool test_30 (void) {
|
||||
return nopoll_false;
|
||||
} /* end if */
|
||||
|
||||
printf ("Test 30: getting reply to the message..\n");
|
||||
printf ("Test %s: getting reply to the message..\n", label);
|
||||
tries = 10;
|
||||
while (tries > 0 ) {
|
||||
/* get message */
|
||||
@@ -2480,13 +2483,16 @@ nopoll_bool test_30 (void) {
|
||||
/* release message */
|
||||
nopoll_msg_unref (msg_ref);
|
||||
|
||||
printf ("Test 30: send second message..\n");
|
||||
|
||||
printf ("Test %s: sending second message (of %d bytes, sending broken header of %d, pausing then, and then sending the rest..)\n",
|
||||
label, length, bytes_to_send_before_stop);
|
||||
|
||||
if (nopoll_conn_send_text (conn, msg, length) != length) {
|
||||
printf ("ERROR: failed to send message..");
|
||||
return nopoll_false;
|
||||
} /* end while */
|
||||
|
||||
printf ("Test 30: getting reply to the message (to the second message)..\n");
|
||||
printf ("Test %s: getting reply to the message (to the second message)..\n", label);
|
||||
tries = 10;
|
||||
while (tries > 0 ) {
|
||||
/* get message */
|
||||
@@ -2520,7 +2526,35 @@ nopoll_bool test_30 (void) {
|
||||
return nopoll_true;
|
||||
}
|
||||
|
||||
nopoll_bool test_30 (void) {
|
||||
/* call to test send 1 byte and stop */
|
||||
return test_30_common_header_stop ("30", 2);
|
||||
}
|
||||
|
||||
nopoll_bool test_31 (void) {
|
||||
/* call to test send 1 byte and stop */
|
||||
return test_30_common_header_stop ("31", 1);
|
||||
}
|
||||
|
||||
nopoll_bool test_32 (void) {
|
||||
/* call to test send 1 byte and stop */
|
||||
return test_30_common_header_stop ("32", 3);
|
||||
}
|
||||
|
||||
nopoll_bool test_33 (void) {
|
||||
/* call to test send 1 byte and stop */
|
||||
return test_30_common_header_stop ("33", 4);
|
||||
}
|
||||
|
||||
nopoll_bool test_34 (void) {
|
||||
/* call to test send 1 byte and stop */
|
||||
return test_30_common_header_stop ("34", 5);
|
||||
}
|
||||
|
||||
nopoll_bool test_35 (void) {
|
||||
/* call to test send 1 byte and stop */
|
||||
return test_30_common_header_stop ("35", 8);
|
||||
}
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
@@ -2832,6 +2866,41 @@ int main (int argc, char ** argv)
|
||||
return -1;
|
||||
} /* end if */
|
||||
|
||||
if (test_31 ()) {
|
||||
printf ("Test 31: simulate stop in the middle of the header send (II) [ OK ]\n");
|
||||
} else {
|
||||
printf ("Test 31: simulate stop in the middle of the header send (II) [ FAILED ]\n");
|
||||
return -1;
|
||||
} /* end if */
|
||||
|
||||
if (test_32 ()) {
|
||||
printf ("Test 32: simulate stop in the middle of the header send (III) [ OK ]\n");
|
||||
} else {
|
||||
printf ("Test 32: simulate stop in the middle of the header send (III) [ FAILED ]\n");
|
||||
return -1;
|
||||
} /* end if */
|
||||
|
||||
if (test_33 ()) {
|
||||
printf ("Test 33: simulate stop in the middle of the header send (IV) [ OK ]\n");
|
||||
} else {
|
||||
printf ("Test 33: simulate stop in the middle of the header send (IV) [ FAILED ]\n");
|
||||
return -1;
|
||||
} /* end if */
|
||||
|
||||
if (test_34 ()) {
|
||||
printf ("Test 34: simulate stop in the middle of the header send (V) [ OK ]\n");
|
||||
} else {
|
||||
printf ("Test 34: simulate stop in the middle of the header send (V) [ FAILED ]\n");
|
||||
return -1;
|
||||
} /* end if */
|
||||
|
||||
if (test_35 ()) {
|
||||
printf ("Test 35: simulate stop in the middle of the header send (VI) [ OK ]\n");
|
||||
} else {
|
||||
printf ("Test 35: simulate stop in the middle of the header send (VI) [ FAILED ]\n");
|
||||
return -1;
|
||||
} /* end if */
|
||||
|
||||
/* add support to reply with redirect 301 to an opening
|
||||
* request: page 19 and 22 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user