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); }
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)); }
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)); }
/** * 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); }
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); }
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); }
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); }
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); } } }
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; }
static gboolean idle_timeout (gpointer conn) { soup_connection_disconnect (conn); return FALSE; }
static void socket_disconnected (SoupSocket *sock, gpointer conn) { soup_connection_disconnect (conn); }