Esempio n. 1
0
/**
 * soup_connection_connect_async:
 * @conn: the connection
 * @callback: callback to call when the connection succeeds or fails
 * @user_data: data for @callback
 *
 * Asynchronously connects @conn.
 **/
void
soup_connection_connect_async (SoupConnection *conn,
			       SoupConnectionCallback callback,
			       gpointer user_data)
{
	SoupConnectionAsyncConnectData *data;
	SoupConnectionPrivate *priv;

	g_return_if_fail (SOUP_IS_CONNECTION (conn));
	priv = SOUP_CONNECTION_GET_PRIVATE (conn);
	g_return_if_fail (priv->socket == NULL);

	soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING);

	data = g_slice_new (SoupConnectionAsyncConnectData);
	data->conn = conn;
	data->callback = callback;
	data->callback_data = user_data;

	priv->socket =
		soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, priv->remote_addr,
				 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
				 SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
				 SOUP_SOCKET_TIMEOUT, priv->io_timeout,
				 NULL);
	soup_socket_connect_async (priv->socket, NULL,
				   socket_connect_result, data);
}
Esempio n. 2
0
gboolean
soup_connection_connect_sync (SoupConnection  *conn,
			      GCancellable    *cancellable,
			      GError         **error)
{
	SoupConnectionPrivate *priv;
	SoupAddress *remote_addr;

	g_return_val_if_fail (SOUP_IS_CONNECTION (conn), FALSE);
	priv = SOUP_CONNECTION_GET_PRIVATE (conn);
	g_return_val_if_fail (priv->socket == NULL, FALSE);

	soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING);

	/* Set the protocol to ensure correct proxy resolution. */
	remote_addr =
		g_object_new (SOUP_TYPE_ADDRESS,
			      SOUP_ADDRESS_NAME, priv->remote_uri->host,
			      SOUP_ADDRESS_PORT, priv->remote_uri->port,
			      SOUP_ADDRESS_PROTOCOL, priv->remote_uri->scheme,
			      NULL);

	priv->socket =
		soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, remote_addr,
				 SOUP_SOCKET_SSL_FALLBACK, priv->ssl_fallback,
				 SOUP_SOCKET_SOCKET_PROPERTIES, priv->socket_props,
				 SOUP_SOCKET_FLAG_NONBLOCKING, FALSE,
				 NULL);
	g_object_unref (remote_addr);

	g_signal_connect (priv->socket, "event",
			  G_CALLBACK (re_emit_socket_event), conn);
	if (!soup_socket_connect_sync_internal (priv->socket, cancellable, error))
		return FALSE;

	priv->proxy_uri = soup_socket_get_http_proxy_uri (priv->socket);

	if (priv->ssl && !priv->proxy_uri) {
		if (!soup_socket_handshake_sync (priv->socket,
						 priv->remote_uri->host,
						 cancellable, error))
			return FALSE;
	}

	if (!priv->ssl || !priv->proxy_uri) {
		soup_connection_event (conn,
				       G_SOCKET_CLIENT_COMPLETE,
				       NULL);
	}
	soup_connection_set_state (conn, SOUP_CONNECTION_IN_USE);
	priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT;
	start_idle_timer (conn);

	return TRUE;
}
Esempio n. 3
0
/**
 * soup_connection_connect_sync:
 * @conn: the connection
 *
 * Synchronously connects @conn.
 *
 * Return value: the soup status
 **/
guint
soup_connection_connect_sync (SoupConnection *conn)
{
	SoupConnectionPrivate *priv;
	guint status;

	g_return_val_if_fail (SOUP_IS_CONNECTION (conn), SOUP_STATUS_MALFORMED);
	priv = SOUP_CONNECTION_GET_PRIVATE (conn);
	g_return_val_if_fail (priv->socket == NULL, SOUP_STATUS_MALFORMED);

	soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING);

	priv->socket =
		soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, priv->remote_addr,
				 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
				 SOUP_SOCKET_FLAG_NONBLOCKING, FALSE,
				 SOUP_SOCKET_TIMEOUT, priv->io_timeout,
				 NULL);

	status = soup_socket_connect_sync (priv->socket, NULL);

	if (!SOUP_STATUS_IS_SUCCESSFUL (status))
		goto fail;
		
	g_signal_connect (priv->socket, "disconnected",
			  G_CALLBACK (socket_disconnected), conn);

	if (priv->ssl_creds && !priv->tunnel_addr) {
		if (!soup_socket_start_ssl (priv->socket, NULL)) {
			status = SOUP_STATUS_SSL_FAILED;
			goto fail;
		}
	}

	if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
		soup_connection_set_state (conn, SOUP_CONNECTION_IDLE);
		priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT;
		start_idle_timer (conn);
	} else {
	fail:
		if (priv->socket) {
			g_object_unref (priv->socket);
			priv->socket = NULL;
		}
	}

	if (priv->proxy_uri != NULL)
		status = soup_status_proxify (status);
	return status;
}
Esempio n. 4
0
static GObject *
constructor (GType                  type,
	     guint                  n_construct_properties,
	     GObjectConstructParam *construct_properties)
{
	GObject *server;
	SoupServerPrivate *priv;

	server = G_OBJECT_CLASS (soup_server_parent_class)->constructor (
		type, n_construct_properties, construct_properties);
	if (!server)
		return NULL;
	priv = SOUP_SERVER_GET_PRIVATE (server);

	if (!priv->interface) {
		priv->interface =
			soup_address_new_any (SOUP_ADDRESS_FAMILY_IPV4,
					      priv->port);
	}

	if (priv->ssl_cert_file && priv->ssl_key_file) {
		priv->ssl_creds = soup_ssl_get_server_credentials (
			priv->ssl_cert_file,
			priv->ssl_key_file);
		if (!priv->ssl_creds) {
			g_object_unref (server);
			return NULL;
		}
	}

	priv->listen_sock =
		soup_socket_new (SOUP_SOCKET_LOCAL_ADDRESS, priv->interface,
				 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
				 SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
				 NULL);
	if (!soup_socket_listen (priv->listen_sock)) {
		g_object_unref (server);
		return NULL;
	}

	/* Re-resolve the interface address, in particular in case
	 * the passed-in address had SOUP_ADDRESS_ANY_PORT.
	 */
	g_object_unref (priv->interface);
	priv->interface = soup_socket_get_local_address (priv->listen_sock);
	g_object_ref (priv->interface);
	priv->port = soup_address_get_port (priv->interface);

	return server;
}
Esempio n. 5
0
void
soup_connection_connect_async (SoupConnection      *conn,
			       GCancellable        *cancellable,
			       GAsyncReadyCallback  callback,
			       gpointer             user_data)
{
	SoupConnectionPrivate *priv;
	SoupAddress *remote_addr;
	GTask *task;

	g_return_if_fail (SOUP_IS_CONNECTION (conn));
	priv = SOUP_CONNECTION_GET_PRIVATE (conn);
	g_return_if_fail (priv->socket == NULL);

	soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING);

	/* Set the protocol to ensure correct proxy resolution. */
	remote_addr =
		g_object_new (SOUP_TYPE_ADDRESS,
			      SOUP_ADDRESS_NAME, priv->remote_uri->host,
			      SOUP_ADDRESS_PORT, priv->remote_uri->port,
			      SOUP_ADDRESS_PROTOCOL, priv->remote_uri->scheme,
			      NULL);

	priv->socket =
		soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, remote_addr,
				 SOUP_SOCKET_SSL_FALLBACK, priv->ssl_fallback,
				 SOUP_SOCKET_SOCKET_PROPERTIES, priv->socket_props,
				 NULL);
	g_object_unref (remote_addr);

	g_signal_connect (priv->socket, "event",
			  G_CALLBACK (re_emit_socket_event), conn);

	soup_socket_properties_push_async_context (priv->socket_props);
	task = g_task_new (conn, cancellable, callback, user_data);

	soup_socket_connect_async_internal (priv->socket, cancellable,
					    socket_connect_complete, task);
	soup_socket_properties_pop_async_context (priv->socket_props);
}
Esempio n. 6
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;
}