示例#1
0
static void
async_write (SoupSocket *sock, gpointer user_data)
{
	AsyncData *data = user_data;
	SoupSocketIOStatus status;
	gsize n;
	GError *error = NULL;

	do {
		status = soup_socket_write (sock, data->writebuf + data->total,
					    BUFSIZE - data->total, &n,
					    NULL, &error);
		if (status == SOUP_SOCKET_OK)
			data->total += n;
	} while (status == SOUP_SOCKET_OK && data->total < BUFSIZE);

	if (status == SOUP_SOCKET_ERROR || status == SOUP_SOCKET_EOF) {
		g_error ("Async write got status %d: %s", status,
			 error ? error->message : "(unknown)");
	} else if (status == SOUP_SOCKET_WOULD_BLOCK)
		return;

	data->total = 0;
	async_read (sock, user_data);
}
示例#2
0
/* Attempts to write @len bytes from @data. See the note at
 * read_metadata() for an explanation of the return value.
 */
static gboolean
write_data (SoupMessage *msg, const char *data, guint len, gboolean body)
{
	SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
	SoupMessageIOData *io = priv->io_data;
	SoupSocketIOStatus status;
	gsize nwrote;
	GError *error = NULL;
	SoupBuffer *chunk;
	const char *start;

	while (len > io->written) {
		status = soup_socket_write (io->sock,
					    data + io->written,
					    len - io->written,
					    &nwrote, NULL, &error);
		switch (status) {
		case SOUP_SOCKET_EOF:
		case SOUP_SOCKET_ERROR:
			io_error (io->sock, msg, error);
			return FALSE;

		case SOUP_SOCKET_WOULD_BLOCK:
			return FALSE;

		case SOUP_SOCKET_OK:
			start = data + io->written;
			io->written += nwrote;

			if (body) {
				if (io->write_length)
					io->write_length -= nwrote;

				chunk = soup_buffer_new (SOUP_MEMORY_TEMPORARY,
							 start, nwrote);
				SOUP_MESSAGE_IO_PREPARE_FOR_CALLBACK;
				soup_message_wrote_body_data (msg, chunk);
				soup_buffer_free (chunk);
				SOUP_MESSAGE_IO_RETURN_VAL_IF_CANCELLED_OR_PAUSED (FALSE);
			}
			break;
		}
	}

	io->written = 0;
	return TRUE;
}
示例#3
0
int
main (int argc, char **argv)
{
	int opt, debug = 0, listener, sin_len, port, i;
	struct sockaddr_in sin;
	GThread *server;
	char writebuf[BUFSIZE], readbuf[BUFSIZE];
	SoupAddress *addr;
	SoupSSLCredentials *creds;
	SoupSocket *sock;
	gsize n, total;
	SoupSocketIOStatus status;
	int connect_status;
	GError *error = NULL;

	g_thread_init (NULL);
	g_type_init ();

	/* On Windows, this will call WSAStartup() */
	soup_socket_get_type ();

	while ((opt = getopt (argc, argv, "c:d:k:")) != -1) {
		switch (opt) {
		case 'c':
			ssl_cert_file = optarg;
			break;
		case 'd':
			debug = atoi (optarg);
			break;
		case 'k':
			ssl_key_file = optarg;
			break;

		case '?':
			fprintf (stderr, "Usage: %s [-d debuglevel] [-c ssl-cert-file] [-k ssl-key-file]\n",
				 argv[0]);
			break;
		}
	}

	if (debug) {
		gnutls_global_set_log_function (debug_log);
		gnutls_global_set_log_level (debug);
	}

	/* Create server socket */
	listener = socket (AF_INET, SOCK_STREAM, 0);
	if (listener == -1) {
		SOCKET_PRINT_ERROR ("creating listening socket");
		exit (1);
	}

	memset (&sin, 0, sizeof (sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = ntohl (INADDR_LOOPBACK);

	if (bind (listener, (struct sockaddr *) &sin, sizeof (sin))  == -1) {
		SOCKET_PRINT_ERROR ("binding listening socket");
		exit (1);
	}

	if (listen (listener, 1) == -1) {
		SOCKET_PRINT_ERROR ("listening on socket");
		exit (1);
	}

	sin_len = sizeof (sin);
	getsockname (listener, (struct sockaddr *)&sin, (void *)&sin_len);
	port = ntohs (sin.sin_port);

	/* Create the client */
	addr = soup_address_new ("127.0.0.1", port);
	creds = soup_ssl_get_client_credentials (NULL);
	sock = soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, addr,
				SOUP_SOCKET_FLAG_NONBLOCKING, FALSE,
				SOUP_SOCKET_SSL_CREDENTIALS, creds,
				NULL);
	g_object_unref (addr);
	connect_status = soup_socket_connect_sync (sock, NULL);
	if (connect_status != SOUP_STATUS_OK) {
		g_error ("Could not create client socket: %s",
			 soup_status_get_phrase (connect_status));
	}

	soup_socket_start_ssl (sock, NULL);

	/* Now spawn server thread */
	server = g_thread_create (server_thread, GINT_TO_POINTER (listener),
				  TRUE, NULL);

	/* Synchronous client test */
	for (i = 0; i < BUFSIZE; i++)
		writebuf[i] = i & 0xFF;

	total = 0;
	while (total < BUFSIZE) {
		status = soup_socket_write (sock, writebuf + total,
					    BUFSIZE - total, &n,
					    NULL, &error);
		if (status != SOUP_SOCKET_OK)
			g_error ("Sync write got status %d: %s", status,
				 error ? error->message : "(unknown)");
		total += n;
	}

	total = 0;
	while (total < BUFSIZE) {
		status = soup_socket_read (sock, readbuf + total,
					   BUFSIZE - total, &n,
					   NULL, &error);
		if (status != SOUP_SOCKET_OK)
			g_error ("Sync read got status %d: %s", status,
				 error ? error->message : "(unknown)");
		total += n;
	}

	if (memcmp (writebuf, readbuf, BUFSIZE) != 0)
		g_error ("Sync read didn't match write");

	printf ("SYNCHRONOUS SSL TEST PASSED\n");

	/* Switch socket to async and do it again */

	g_object_set (sock,
		      SOUP_SOCKET_FLAG_NONBLOCKING, TRUE,
		      NULL);

	g_idle_add (start_writing, sock);
	loop = g_main_loop_new (NULL, TRUE);
	g_main_loop_run (loop);
	g_main_loop_unref (loop);
	g_main_context_unref (g_main_context_default ());

	printf ("ASYNCHRONOUS SSL TEST PASSED\n");

	g_object_unref (sock);
	soup_ssl_free_client_credentials (creds);
	g_thread_join (server);

	/* Success */
	return 0;
}