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;
}
Beispiel #2
0
/** 
 * @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");
}
Beispiel #4
0
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;
}