Пример #1
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);
}
Пример #2
0
void
soup_connection_set_state (SoupConnection *conn, SoupConnectionState state)
{
	SoupConnectionPrivate *priv;

	g_return_if_fail (SOUP_IS_CONNECTION (conn));
	g_return_if_fail (state >= SOUP_CONNECTION_NEW &&
			  state <= SOUP_CONNECTION_DISCONNECTED);

	g_object_freeze_notify (G_OBJECT (conn));

	priv = SOUP_CONNECTION_GET_PRIVATE (conn);

	if (priv->current_msg) {
		g_warn_if_fail (state == SOUP_CONNECTION_IDLE ||
				state == SOUP_CONNECTION_DISCONNECTED);
		clear_current_msg (conn);
	}

	if (state == SOUP_CONNECTION_IDLE && !priv->reusable) {
		/* This will recursively call set_state() */
		soup_connection_disconnect (conn);
	} else {
		priv->state = state;

		if (priv->state == SOUP_CONNECTION_IDLE)
			start_idle_timer (conn);

		g_object_notify (G_OBJECT (conn), "state");
	}

	g_object_thaw_notify (G_OBJECT (conn));
}
Пример #3
0
static void
clear_current_request (SoupConnection *conn)
{
	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);

	g_object_freeze_notify (G_OBJECT (conn));

	if (priv->state == SOUP_CONNECTION_IN_USE) {
		/* We don't use soup_connection_set_state here since
		 * it may call clear_current_request()...
		 */
		priv->state = SOUP_CONNECTION_IDLE;
		g_object_notify (G_OBJECT (conn), "state");
	}
	start_idle_timer (conn);
	if (priv->cur_req) {
		SoupMessage *cur_req = priv->cur_req;

		g_object_remove_weak_pointer (G_OBJECT (priv->cur_req),
					      (gpointer)&priv->cur_req);
		priv->cur_req = NULL;
		g_object_notify (G_OBJECT (conn), "message");

		if (!soup_message_is_keepalive (cur_req))
			soup_connection_disconnect (conn);
		else
			soup_message_io_stop (cur_req);
	}

	g_object_thaw_notify (G_OBJECT (conn));
}
Пример #4
0
/**
 * soup_session_abort:
 * @session: the session
 *
 * Cancels all pending requests in @session.
 **/
void
soup_session_abort (SoupSession *session)
{
	SoupSessionPrivate *priv;
	SoupMessageQueueItem *item;
	GSList *conns, *c;

	g_return_if_fail (SOUP_IS_SESSION (session));
	priv = SOUP_SESSION_GET_PRIVATE (session);

	for (item = soup_message_queue_first (priv->queue);
	     item;
	     item = soup_message_queue_next (priv->queue, item)) {
		soup_session_cancel_message (session, item->msg,
					     SOUP_STATUS_CANCELLED);
	}

	/* Close all connections */
	g_mutex_lock (priv->host_lock);
	conns = NULL;
	g_hash_table_foreach (priv->conns, gather_conns, &conns);

	g_mutex_unlock (priv->host_lock);
	for (c = conns; c; c = c->next) {
		soup_connection_disconnect (c->data);
		g_object_unref (c->data);
	}

	g_slist_free (conns);
}
Пример #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);
}
Пример #6
0
static void
free_host (SoupSessionHost *host)
{
	while (host->connections) {
		SoupConnection *conn = host->connections->data;

		host->connections = g_slist_remove (host->connections, conn);
		soup_connection_disconnect (conn);
	}

	soup_uri_free (host->uri);
	g_object_unref (host->addr);
	g_slice_free (SoupSessionHost, host);
}	
Пример #7
0
static void
dispose (GObject *object)
{
	SoupConnection *conn = SOUP_CONNECTION (object);
	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);

	stop_idle_timer (priv);
	/* Make sure clear_current_request doesn't re-establish the timeout */
	priv->idle_timeout = 0;

	clear_current_request (conn);
	soup_connection_disconnect (conn);

	G_OBJECT_CLASS (soup_connection_parent_class)->dispose (object);
}
Пример #8
0
static void
clear_current_request (SoupConnection *conn)
{
	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);

	if (priv->state == SOUP_CONNECTION_IN_USE)
		priv->state = SOUP_CONNECTION_IDLE;
	start_idle_timer (conn);
	if (priv->cur_req) {
		SoupMessage *cur_req = priv->cur_req;

		g_object_remove_weak_pointer (G_OBJECT (priv->cur_req),
					      (gpointer)&priv->cur_req);
		priv->cur_req = NULL;

		if (!soup_message_is_keepalive (cur_req))
			soup_connection_disconnect (conn);
		else {
			priv->last_used = time (NULL);
			soup_message_io_stop (cur_req);
		}
	}
}
Пример #9
0
gboolean
soup_session_try_prune_connection (SoupSession *session)
{
	SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
	GPtrArray *conns;
	GHashTableIter iter;
	gpointer conn, host;
	int i;

	conns = g_ptr_array_new ();

	g_mutex_lock (priv->host_lock);
	g_hash_table_iter_init (&iter, priv->conns);
	while (g_hash_table_iter_next (&iter, &conn, &host)) {
		/* Don't prune a connection that is currently in use,
		 * or hasn't been used yet.
		 */
		if (soup_connection_get_state (conn) == SOUP_CONNECTION_IDLE &&
		    soup_connection_last_used (conn) > 0)
			g_ptr_array_add (conns, g_object_ref (conn));
	}
	g_mutex_unlock (priv->host_lock);

	if (!conns->len) {
		g_ptr_array_free (conns, TRUE);
		return FALSE;
	}

	for (i = 0; i < conns->len; i++) {
		soup_connection_disconnect (conns->pdata[i]);
		g_object_unref (conns->pdata[i]);
	}
	g_ptr_array_free (conns, TRUE);

	return TRUE;
}
Пример #10
0
static gboolean
idle_timeout (gpointer conn)
{
	soup_connection_disconnect (conn);
	return FALSE;
}
Пример #11
0
static void
socket_disconnected (SoupSocket *sock, gpointer conn)
{
	soup_connection_disconnect (conn);
}