Esempio n. 1
0
static void
got_connection (SoupConnection *conn, guint status, gpointer session)
{
	SoupAddress *tunnel_addr;

	if (status != SOUP_STATUS_OK) {
		/* There may have been messages waiting for the
		 * connection count to go down, so queue a run_queue.
		 */
		do_idle_run_queue (session);

		soup_session_connection_failed (session, conn, status);
		/* session may be destroyed at this point */

		return;
	}

	tunnel_addr = soup_connection_get_tunnel_addr (conn);
	if (tunnel_addr) {
		SoupSessionAsyncTunnelData *data;

		data = g_slice_new (SoupSessionAsyncTunnelData);
		data->session = session;
		data->conn = conn;
		data->item = soup_session_make_connect_message (session, tunnel_addr);
		g_signal_emit_by_name (session, "tunneling", conn);
		g_signal_connect (data->item->msg, "finished",
				  G_CALLBACK (tunnel_connected), data);
		g_signal_connect (data->item->msg, "restarted",
				  G_CALLBACK (tunnel_connected), data);
		soup_session_send_queue_item (session, data->item, conn);
		return;
	}

	g_signal_connect (conn, "disconnected",
			  G_CALLBACK (connection_closed), session);

	/* @conn has been marked reserved by SoupSession, but
	 * we don't actually have any specific message in mind
	 * for it. (In particular, the message we were
	 * originally planning to queue on it may have already
	 * been queued on some other connection that became
	 * available while we were waiting for this one to
	 * connect.) So we release the connection into the
	 * idle pool and then just run the queue and see what
	 * happens.
	 */
	soup_connection_set_state (conn, SOUP_CONNECTION_IDLE);
	do_idle_run_queue (session);
}
Esempio n. 2
0
static void
tunnel_connected (SoupMessage *msg, gpointer user_data)
{
	SoupSessionAsyncTunnelData *data = user_data;

	if (SOUP_MESSAGE_IS_STARTING (msg)) {
		soup_session_send_queue_item (data->session, data->item, data->conn);
		return;
	}

	if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
		soup_session_connection_failed (data->session, data->conn,
						msg->status_code);
		goto done;
	}

	if (!soup_connection_start_ssl (data->conn)) {
		soup_session_connection_failed (data->session, data->conn,
						SOUP_STATUS_SSL_FAILED);
		goto done;
	}

	g_signal_connect (data->conn, "disconnected",
			  G_CALLBACK (connection_closed), data->session);
	soup_connection_set_state (data->conn, SOUP_CONNECTION_IDLE);

	do_idle_run_queue (data->session);

done:
	soup_message_queue_item_unref (data->item);
	g_slice_free (SoupSessionAsyncTunnelData, data);
}
Esempio n. 3
0
static void
queue_message (SoupSession *session, SoupMessage *req,
	       SoupSessionCallback callback, gpointer user_data)
{
	SOUP_SESSION_CLASS (soup_session_async_parent_class)->queue_message (session, req, callback, user_data);

	do_idle_run_queue (session);
}
Esempio n. 4
0
static void
connection_closed (SoupConnection *conn, gpointer session)
{
	/* Run the queue in case anyone was waiting for a connection
	 * to be closed.
	 */
	do_idle_run_queue (session);
}
Esempio n. 5
0
static void
got_connection (SoupConnection *conn, guint status, gpointer user_data)
{
	SoupMessageQueueItem *item = user_data;
	SoupSession *session = item->session;
	SoupAddress *tunnel_addr;

	if (item->state != SOUP_MESSAGE_CONNECTING) {
		soup_connection_disconnect (conn);
		do_idle_run_queue (session);
		soup_message_queue_item_unref (item);
		g_object_unref (session);
		return;
	}

	if (status != SOUP_STATUS_OK) {
		soup_session_set_item_status (session, item, status);
		item->state = SOUP_MESSAGE_FINISHING;

		soup_connection_disconnect (conn);
		do_idle_run_queue (session);
		soup_message_queue_item_unref (item);
		g_object_unref (session);
		return;
	}

	tunnel_addr = soup_connection_get_tunnel_addr (conn);
	if (tunnel_addr) {
		SoupMessageQueueItem *tunnel_item;

		item->state = SOUP_MESSAGE_TUNNELING;

		tunnel_item = soup_session_make_connect_message (session, conn);
		tunnel_item->related = item;
		soup_session_send_queue_item (session, tunnel_item, tunnel_message_completed);
		return;
	}

	item->state = SOUP_MESSAGE_READY;
	g_signal_connect (conn, "disconnected",
			  G_CALLBACK (connection_closed), session);
	run_queue ((SoupSessionAsync *)session);
	soup_message_queue_item_unref (item);
	g_object_unref (session);
}
Esempio n. 6
0
static void
message_completed (SoupMessage *msg, gpointer user_data)
{
	SoupMessageQueueItem *item = user_data;

	if (item->state != SOUP_MESSAGE_RESTARTING)
		item->state = SOUP_MESSAGE_FINISHING;
	do_idle_run_queue (item->session);
}
Esempio n. 7
0
static void
tunnel_message_completed (SoupMessage *msg, gpointer user_data)
{
	SoupMessageQueueItem *item = user_data;
	SoupSession *session = item->session;

	if (item->state == SOUP_MESSAGE_RESTARTING) {
		soup_message_restarted (msg);
		if (item->conn) {
			soup_session_send_queue_item (session, item, tunnel_message_completed);
			return;
		}

		soup_message_set_status (msg, SOUP_STATUS_TRY_AGAIN);
	}

	item->state = SOUP_MESSAGE_FINISHED;

	if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
		if (item->conn)
			soup_connection_disconnect (item->conn);
		if (msg->status_code == SOUP_STATUS_TRY_AGAIN) {
			item->related->state = SOUP_MESSAGE_AWAITING_CONNECTION;
			g_object_unref (item->related->conn);
			item->related->conn = NULL;
		} else
			soup_message_set_status (item->related->msg, msg->status_code);
		goto done;
	}

	if (!soup_connection_start_ssl (item->conn)) {
		if (item->conn)
			soup_connection_disconnect (item->conn);
		soup_message_set_status (item->related->msg, SOUP_STATUS_SSL_FAILED);
		goto done;
	}

	g_signal_connect (item->conn, "disconnected",
			  G_CALLBACK (connection_closed), item->session);
	soup_connection_set_state (item->conn, SOUP_CONNECTION_IDLE);
	soup_connection_set_state (item->conn, SOUP_CONNECTION_IN_USE);

	item->related->state = SOUP_MESSAGE_READY;

done:
	soup_message_finished (msg);
	if (item->related->msg->status_code)
		item->related->state = SOUP_MESSAGE_FINISHING;

	do_idle_run_queue (item->session);
	soup_message_queue_item_unref (item->related);
	soup_session_unqueue_item (session, item);
	soup_message_queue_item_unref (item);
	g_object_unref (session);
}
Esempio n. 8
0
static void
queue_message (SoupSession *session, SoupMessage *req,
	       SoupSessionCallback callback, gpointer user_data)
{
	SoupMessageQueueItem *item;

	SOUP_SESSION_CLASS (soup_session_async_parent_class)->queue_message (session, req, callback, user_data);

	item = soup_message_queue_lookup (soup_session_get_queue (session), req);
	g_return_if_fail (item != NULL);

	g_signal_connect (req, "restarted",
			  G_CALLBACK (request_restarted), item);
	g_signal_connect_after (req, "finished",
				G_CALLBACK (final_finished), item);

	do_idle_run_queue (session);
}
Esempio n. 9
0
static gboolean
item_failed (SoupMessageQueueItem *item, guint status)
{
	if (item->removed) {
		soup_message_queue_item_unref (item);
		return TRUE;
	}

	if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
		item->state = SOUP_MESSAGE_FINISHING;
		if (!item->msg->status_code)
			soup_session_set_item_status (item->session, item, status);
		do_idle_run_queue (item->session);
		soup_message_queue_item_unref (item);
		return TRUE;
	}

	return FALSE;
}
Esempio n. 10
0
static void
final_finished (SoupMessage *req, gpointer user_data)
{
	SoupMessageQueueItem *item = user_data;
	SoupSession *session = item->session;

	g_object_ref (session);

	if (!SOUP_MESSAGE_IS_STARTING (req)) {
		g_signal_handlers_disconnect_by_func (req, final_finished, item);
		g_signal_handlers_disconnect_by_func (req, request_restarted, item);
		if (item->callback)
			item->callback (session, req, item->callback_data);

		g_object_unref (req);
		soup_message_queue_item_unref (item);
	}

	do_idle_run_queue (session);
	g_object_unref (session);
}
Esempio n. 11
0
static void
process_queue_item (SoupMessageQueueItem *item,
		    gboolean             *should_prune,
		    gboolean              loop)
{
	SoupSession *session = item->session;
	SoupProxyURIResolver *proxy_resolver;

	do {
		switch (item->state) {
		case SOUP_MESSAGE_STARTING:
			proxy_resolver = (SoupProxyURIResolver *)soup_session_get_feature_for_message (session, SOUP_TYPE_PROXY_URI_RESOLVER, item->msg);
			if (!proxy_resolver) {
				item->state = SOUP_MESSAGE_AWAITING_CONNECTION;
				break;
			}
			resolve_proxy_addr (item, proxy_resolver);
			return;

		case SOUP_MESSAGE_AWAITING_CONNECTION:
			if (!soup_session_get_connection (session, item, should_prune))
				return;

			if (soup_connection_get_state (item->conn) != SOUP_CONNECTION_NEW) {
				item->state = SOUP_MESSAGE_READY;
				break;
			}

			item->state = SOUP_MESSAGE_CONNECTING;
			soup_message_queue_item_ref (item);
			g_object_ref (session);
			soup_connection_connect_async (item->conn, item->cancellable,
						       got_connection, item);
			return;

		case SOUP_MESSAGE_READY:
			item->state = SOUP_MESSAGE_RUNNING;
			soup_session_send_queue_item (session, item, message_completed);
			break;

		case SOUP_MESSAGE_RESTARTING:
			item->state = SOUP_MESSAGE_STARTING;
			soup_message_restarted (item->msg);
			break;

		case SOUP_MESSAGE_FINISHING:
			item->state = SOUP_MESSAGE_FINISHED;
			soup_message_finished (item->msg);
			if (item->state != SOUP_MESSAGE_FINISHED)
				break;

			g_object_ref (session);
			soup_session_unqueue_item (session, item);
			if (item->callback)
				item->callback (session, item->msg, item->callback_data);
			g_object_unref (item->msg);
			do_idle_run_queue (session);
			g_object_unref (session);
			return;

		default:
			/* Nothing to do with this message in any
			 * other state.
			 */
			return;
		}
	} while (loop && item->state != SOUP_MESSAGE_FINISHED);
}