static void send_eof_and_close(Channel * channel, int err) { ChannelNP * c = channel2np(channel); assert(c->magic == CHANNEL_MAGIC); if (channel->state == ChannelStateDisconnected) return; ibuf_flush(&c->ibuf); if (c->ibuf.handling_msg == HandleMsgTriggered) { /* Cancel pending message handling */ cancel_event(handle_channel_msg, c, 0); c->ibuf.handling_msg = HandleMsgIdle; } write_stream(&c->chan.out, MARKER_EOS); write_errno(&c->chan.out, err); write_stream(&c->chan.out, MARKER_EOM); np_flush_with_flags(c, 0); #if ENABLE_OutputQueue if (output_queue_is_empty(&c->out_queue)) #endif nopoll_conn_shutdown(c->np_socket); c->chan.state = ChannelStateDisconnected; np_post_read(&c->ibuf, c->ibuf.buf, c->ibuf.buf_size); notify_channel_closed(channel); if (channel->disconnected) { channel->disconnected(channel); } else { trace(LOG_PROTOCOL, "channel %#lx disconnected", c); if (channel->protocol != NULL) protocol_release(channel->protocol); } channel->protocol = NULL; }
/** * @internal Function used to detected which connections has something * interesting to be notified. * */ nopoll_bool nopoll_loop_process (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data) { int * conn_changed = (int *) user_data; /* check if the connection have something to notify */ if (ctx->io_engine->isset (ctx, conn->session, ctx->io_engine->io_object)) { /* call to notify action according to role */ switch (conn->role) { case NOPOLL_ROLE_CLIENT: case NOPOLL_ROLE_LISTENER: /* received data, notify */ nopoll_loop_process_data (ctx, conn); break; case NOPOLL_ROLE_MAIN_LISTENER: /* call to handle */ nopoll_conn_accept (ctx, conn); break; default: nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Found connection with unknown role, closing and dropping"); nopoll_conn_shutdown (conn); break; } /* reduce connection changed */ (*conn_changed)--; } /* end if */ return (*conn_changed) == 0; }
static void done_write_request(void * args) { ChannelNP * c = (ChannelNP *)((AsyncReqInfo *)args)->client_data; int size = 0; int error = 0; assert(args == &c->wr_req); assert(c->socket != NOPOLL_INVALID_SOCKET); loc_free(((AsyncReqInfo *)args)->u.user.data); if (c->wr_req.u.user.rval < 0) error = c->wr_req.error; size = c->wr_req.u.user.rval; output_queue_done(&c->out_queue, error, size); if (error) c->out_errno = error; if (output_queue_is_empty(&c->out_queue) && c->chan.state == ChannelStateDisconnected) nopoll_conn_shutdown(c->np_socket); np_unlock(&c->chan); trace(LOG_PROTOCOL, "done_write_request"); }
void __myqtt_web_socket_close_conn (noPollConn * conn) { nopoll_conn_shutdown (conn); nopoll_conn_close (conn); return; }
void listener_on_message (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data) { const char * content = (const char *) nopoll_msg_get_payload (msg); FILE * file = NULL; char buffer[1024]; int bytes; int sent; char example[100]; int shown; noPollMsg * aux; nopoll_bool dont_reply = nopoll_false; FILE * open_file_cmd = NULL; int iterator; char * ref; /* check for open file commands */ if (nopoll_ncmp (content, "open-file: ", 11)) { #if defined(NOPOLL_OS_WIN32) open_file_cmd = fopen (content + 11, "ab"); #else open_file_cmd = fopen (content + 11, "a"); #endif if (open_file_cmd == NULL) { printf ("ERROR: unable to open file: %s\n", content + 11); return; } /* end if */ /* set handler */ nopoll_conn_set_on_msg (conn, write_file_handler, open_file_cmd); return; } /* 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); previous_msg = NULL; return; } /* end if */ if (nopoll_ncmp (content, "get-cookie", 10)) { printf ("Listener: reporting cookie: %s\n", nopoll_conn_get_cookie (conn)); nopoll_conn_send_text (conn, nopoll_conn_get_cookie (conn), strlen (nopoll_conn_get_cookie (conn))); return; } /* printf ("Checking for set-broken socket: %s\n", content); */ if (nopoll_ncmp (content, "set-broken-socket", 17)) { printf ("Listener: setting broken socket on conn: %p (socket=%d)\n", conn, (int) nopoll_conn_socket (conn)); nopoll_conn_shutdown (conn); return; } /* end if */ if (nopoll_ncmp (content, "get-connection-close-count", 26)) { printf ("Sending reply to report connection close...\n"); ref = nopoll_strdup_printf ("%d", connection_close_count); nopoll_conn_send_text (conn, ref, strlen (ref)); nopoll_free (ref); return; } /* end if */ if (nopoll_ncmp (content, "1234-1) ", 8)) { printf ("Listener: waiting a second to force buffer flooding..\n"); nopoll_sleep (100000); dont_reply = nopoll_true; } /* end if */ /* get initial bytes */ bytes = nopoll_msg_get_payload_size (msg); shown = bytes > 100 ? 99 : bytes; memset (example, 0, 100); /* if (! nopoll_msg_is_fragment (msg)) */ memcpy (example, (const char *) nopoll_msg_get_payload (msg), shown); printf ("Listener received (size: %d, ctx refs: %d): (first %d bytes, fragment: %d) '%s'\n", nopoll_msg_get_payload_size (msg), nopoll_ctx_ref_count (ctx), shown, nopoll_msg_is_fragment (msg), example); if (nopoll_cmp (content, "ping")) { /* send a ping */ nopoll_conn_send_ping (conn); return; } else if (nopoll_cmp (content, "get-file")) { iterator = 0; file = NULL; while (nopoll_true) { #if defined(NOPOLL_OS_WIN32) file = fopen ("nopoll-regression-client.c", "rb"); #else file = fopen ("nopoll-regression-client.c", "r"); #endif printf ("LISTENER: file pointer (%p, errno=%d : %s)..\n", file, errno, strerror (errno)); if (file) break; iterator++; if (iterator > 3) { printf ("ERROR: failed to open nopoll-regression-client.c (fopen call failed)\n"); nopoll_conn_shutdown (conn); return; } /* end if */ } /* end while */ while (! feof (file)) { /* read content */ bytes = fread (buffer, 1, 1024, file); /* send content */ if (bytes > 0) { /* send content and get the result */ /* printf ("Sending message with %d bytes..\n", bytes); */ /* nopoll_log_enable (ctx, nopoll_true); */ while (nopoll_true) { /* try to send content */ sent = nopoll_conn_send_text (conn, buffer, bytes); /* nopoll_log_enable (ctx, nopoll_false); */ if (sent != bytes) { if (errno == NOPOLL_EWOULDBLOCK) { nopoll_sleep (1000); /* printf (" ..retrying..sending message with %d bytes..\n", bytes); */ continue; } /* end if */ printf ("ERROR: expected to send %d bytes but sent different content size (%d bytes), errno=%d (%d)..\n", bytes, sent, errno, NOPOLL_EWOULDBLOCK); } /* end if */ break; } } /* end if */ /* next */ } /* end while */ /* now close the handle */ fclose (file); return; } /* end if */ /* check if we have to reply */ if (dont_reply) return; if (nopoll_msg_is_fragment (msg)) { printf ("Found fragment, FIN = %d (%p)?..\n", nopoll_msg_is_final (msg), msg); /* call to join this message */ aux = previous_msg; previous_msg = nopoll_msg_join (previous_msg, msg); nopoll_msg_unref (aux); if (! nopoll_msg_is_final (msg)) { printf ("Found fragment that is not final..\n"); printf ("Not replying because frame fragment received..\n"); return; } /* end if */ printf ("Found final fragment, replying with complete content: %s (refs: %d)..\n", (const char *) nopoll_msg_get_payload (previous_msg), nopoll_msg_ref_count (previous_msg)); /* ok, now found final piece, replying */ nopoll_conn_send_text (conn, (const char *) nopoll_msg_get_payload (previous_msg), nopoll_msg_get_payload_size (previous_msg)); /* release reference */ nopoll_msg_unref (previous_msg); previous_msg = NULL; return; } /* send reply as received */ printf ("Sending reply... (same message size: %d)\n", nopoll_msg_get_payload_size (msg)); nopoll_conn_send_text (conn, (const char *) nopoll_msg_get_payload (msg), nopoll_msg_get_payload_size (msg)); return; }