mirror of
https://github.com/outbackdingo/parodus.git
synced 2026-01-28 02:20:02 +00:00
nopoll:
* [new] Updated noPoll conn API to include a new function to allow closing a connection, sending an error message and an error code along with it: - nopoll_conn_close_ext * [fix] Added regression test (test_28) to check connection close frame with status and reason to check functions added: - nopoll_conn_get_close_status - nopoll_conn_get_close_reason Everything working as expected..
This commit is contained in:
@@ -30,6 +30,7 @@ nopoll_conn_accept_complete
|
||||
nopoll_conn_accept_socket
|
||||
nopoll_conn_check_mime_header_repeated
|
||||
nopoll_conn_close
|
||||
nopoll_conn_close_ext
|
||||
nopoll_conn_complete_handshake
|
||||
nopoll_conn_complete_handshake_check
|
||||
nopoll_conn_complete_handshake_check_client
|
||||
|
||||
@@ -1455,10 +1455,18 @@ void nopoll_conn_shutdown (noPollConn * conn)
|
||||
* (\ref noPollRole).
|
||||
*
|
||||
* @param conn The connection to close.
|
||||
*
|
||||
* @param status Optional status code to send to remote side. If
|
||||
* status is < 0, no status code is sent.
|
||||
*
|
||||
* @param reason Pointer to the content to be sent.
|
||||
*
|
||||
* @param reason_size The amount of bytes that should be used from content pointer.
|
||||
*/
|
||||
void nopoll_conn_close (noPollConn * conn)
|
||||
void nopoll_conn_close_ext (noPollConn * conn, int status, const char * reason, int reason_size)
|
||||
{
|
||||
int refs;
|
||||
int refs;
|
||||
char * content;
|
||||
#if defined(SHOW_DEBUG_LOG)
|
||||
const char * role = "unknown";
|
||||
#endif
|
||||
@@ -1483,7 +1491,28 @@ void nopoll_conn_close (noPollConn * conn)
|
||||
if (conn->session != NOPOLL_INVALID_SOCKET) {
|
||||
nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "requested proper connection close id=%d (session %d)", conn->id, conn->session);
|
||||
|
||||
/* send close message */
|
||||
/* build reason indication */
|
||||
content = NULL;
|
||||
if (reason && reason_size > 0) {
|
||||
/* send content */
|
||||
content = nopoll_new (char, reason_size + 3);
|
||||
if (content) {
|
||||
nopoll_set_16bit (status, content);
|
||||
memcpy (content + 2, reason, reason_size);
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
/* send close without reason */
|
||||
nopoll_conn_send_frame (conn, nopoll_true /* has_fin */,
|
||||
/* masked */
|
||||
conn->role == NOPOLL_ROLE_CLIENT, NOPOLL_CLOSE_FRAME,
|
||||
/* content size and content */
|
||||
reason_size > 0 ? reason_size + 2 : 0, content,
|
||||
/* sleep in header */
|
||||
0);
|
||||
|
||||
/* release content (if defined) */
|
||||
nopoll_free (content);
|
||||
|
||||
/* call to shutdown connection */
|
||||
nopoll_conn_shutdown (conn);
|
||||
@@ -1501,6 +1530,23 @@ void nopoll_conn_close (noPollConn * conn)
|
||||
/* call to unref connection */
|
||||
nopoll_conn_unref (conn);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allows to close an opened \ref noPollConn no matter its role
|
||||
* (\ref noPollRole).
|
||||
*
|
||||
* @param conn The connection to close.
|
||||
*
|
||||
* There is available an alternative extended version that allows to
|
||||
* send the status code and the error message: \ref
|
||||
* nopoll_conn_close_ext
|
||||
*/
|
||||
void nopoll_conn_close (noPollConn * conn)
|
||||
{
|
||||
/* call to close without providing a reason */
|
||||
nopoll_conn_close_ext (conn, 0, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,8 @@ void nopoll_conn_shutdown (noPollConn * conn);
|
||||
|
||||
void nopoll_conn_close (noPollConn * conn);
|
||||
|
||||
void nopoll_conn_close_ext (noPollConn * conn, int status, const char * reason, int reason_size);
|
||||
|
||||
void nopoll_conn_set_hook (noPollConn * conn, noPollPtr ptr);
|
||||
|
||||
noPollPtr nopoll_conn_get_hook (noPollConn * conn);
|
||||
|
||||
@@ -2318,6 +2318,65 @@ nopoll_bool test_27 (void) {
|
||||
}
|
||||
|
||||
|
||||
nopoll_bool test_28 (void) {
|
||||
|
||||
noPollConn * conn;
|
||||
noPollCtx * ctx;
|
||||
noPollMsg * msg;
|
||||
|
||||
/* init context */
|
||||
ctx = create_ctx ();
|
||||
|
||||
/* create connection */
|
||||
conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL);
|
||||
if (! nopoll_conn_is_ok (conn)) {
|
||||
printf ("ERROR: Expected to find proper client connection status, but found error..\n");
|
||||
return nopoll_false;
|
||||
} /* end if */
|
||||
|
||||
/* wait until it is connected */
|
||||
nopoll_conn_wait_until_connection_ready (conn, 5);
|
||||
|
||||
/* send a message to request connection close with a particular message */
|
||||
if (nopoll_conn_send_text (conn, "close with message", 18) != 18) {
|
||||
printf ("ERROR: failed to send close with message..");
|
||||
return nopoll_false;
|
||||
} /* end while */
|
||||
|
||||
/* wait for the reply */
|
||||
while ((msg = nopoll_conn_get_msg (conn)) == NULL) {
|
||||
|
||||
if (! nopoll_conn_is_ok (conn)) {
|
||||
/* connection was closed by remote side */
|
||||
break;
|
||||
} /* end if */
|
||||
|
||||
nopoll_sleep (10000);
|
||||
} /* end if */
|
||||
|
||||
printf ("Test 28: close reason received, statud=%d, message=%s\n",
|
||||
nopoll_conn_get_close_status (conn),
|
||||
nopoll_conn_get_close_reason (conn));
|
||||
if (nopoll_conn_get_close_status (conn) != 1048) {
|
||||
printf ("ERROR: expected different error code..\n");
|
||||
return nopoll_false;
|
||||
}
|
||||
|
||||
if (! nopoll_cmp (nopoll_conn_get_close_reason (conn), "Hey, this is a very reasonable error message")) {
|
||||
printf ("ERROR: expected different error message..\n");
|
||||
return nopoll_false;
|
||||
} /* end if */
|
||||
|
||||
/* close connection */
|
||||
nopoll_conn_close (conn);
|
||||
|
||||
/* release context */
|
||||
nopoll_ctx_unref (ctx);
|
||||
|
||||
return nopoll_true;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
int iterator;
|
||||
@@ -2607,6 +2666,13 @@ int main (int argc, char ** argv)
|
||||
return -1;
|
||||
} /* end if */
|
||||
|
||||
if (test_28 ()) {
|
||||
printf ("Test 28: checking setting protocol [ OK ]\n");
|
||||
} else {
|
||||
printf ("Test 28: chekcing setting protocol [ FAILED ]\n");
|
||||
return -1;
|
||||
} /* end if */
|
||||
|
||||
/* add support to reply with redirect 301 to an opening
|
||||
* request: page 19 and 22 */
|
||||
|
||||
|
||||
@@ -149,6 +149,12 @@ void listener_on_message (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, n
|
||||
} /* end if */
|
||||
|
||||
printf ("Message received: %s\n", content);
|
||||
if (nopoll_ncmp (content, "close with message", 18)) {
|
||||
printf ("Listener: RELEASING connection (closing it) with reason..\n");
|
||||
nopoll_conn_close_ext (conn, 1048, "Hey, this is a very reasonable error message", 44);
|
||||
return;
|
||||
} /* end if */
|
||||
|
||||
if (nopoll_ncmp (content, "release-message", 15)) {
|
||||
printf ("Listener: RELEASING previous message..\n");
|
||||
nopoll_msg_unref (previous_msg);
|
||||
|
||||
Reference in New Issue
Block a user