/** * soup_connection_disconnect: * @conn: a connection * * Disconnects @conn's socket and emits a %disconnected signal. * After calling this, @conn will be essentially useless. **/ void soup_connection_disconnect (SoupConnection *conn) { SoupConnectionPrivate *priv; SoupConnectionState old_state; g_return_if_fail (SOUP_IS_CONNECTION (conn)); priv = SOUP_CONNECTION_GET_PRIVATE (conn); old_state = priv->state; if (old_state != SOUP_CONNECTION_DISCONNECTED) soup_connection_set_state (conn, SOUP_CONNECTION_DISCONNECTED); if (priv->socket) { SoupSocket *socket = priv->socket; g_signal_handlers_disconnect_by_func (socket, G_CALLBACK (re_emit_socket_event), conn); priv->socket = NULL; soup_socket_disconnect (socket); g_object_unref (socket); } if (old_state != SOUP_CONNECTION_DISCONNECTED) g_signal_emit (conn, signals[DISCONNECTED], 0); }
static void close_socket (SoupMessage *msg, gpointer user_data) { SoupSocket *sock = user_data; soup_socket_disconnect (sock); }
/** * soup_connection_disconnect: * @conn: a connection * * Disconnects @conn's socket and emits a %disconnected signal. * After calling this, @conn will be essentially useless. **/ void soup_connection_disconnect (SoupConnection *conn) { SoupConnectionPrivate *priv; g_return_if_fail (SOUP_IS_CONNECTION (conn)); priv = SOUP_CONNECTION_GET_PRIVATE (conn); if (!priv->socket) return; g_signal_handlers_disconnect_by_func (priv->socket, socket_disconnected, conn); soup_socket_disconnect (priv->socket); g_object_unref (priv->socket); priv->socket = NULL; /* Don't emit "disconnected" if we aren't yet connected */ if (priv->state < SOUP_CONNECTION_IDLE) return; soup_connection_set_state (conn, SOUP_CONNECTION_DISCONNECTED); /* NB: this might cause conn to be destroyed. */ g_signal_emit (conn, signals[DISCONNECTED], 0); }
static void snra_server_client_finalize (GObject * object) { SnraServerClient *client = (SnraServerClient *) (object); if (client->disco_sig) { g_signal_handler_disconnect (client->event_pipe, client->disco_sig); client->disco_sig = 0; } if (client->net_event_sig) { g_signal_handler_disconnect (client->event_pipe, client->net_event_sig); client->net_event_sig = 0; } if (client->wrote_info_sig) { g_signal_handler_disconnect (client->event_pipe, client->wrote_info_sig); client->wrote_info_sig = 0; } if (client->need_body_complete) { soup_message_body_complete (client->event_pipe->response_body); } if (client->socket) soup_socket_disconnect (client->socket); g_free (client->host); g_free (client->in_buf); g_free (client->out_buf); G_OBJECT_CLASS (snra_server_client_parent_class)->finalize (object); }
static void snra_server_connection_lost (SnraServerClient * client) { if (client->fired_conn_lost) return; client->fired_conn_lost = TRUE; g_print ("Lost connection for client %u\n", client->conn_id); if (client->io) { g_source_remove (client->io_watch); g_io_channel_shutdown (client->io, TRUE, NULL); g_io_channel_unref (client->io); client->io = NULL; } if (client->type == SNRA_SERVER_CLIENT_CHUNKED || client->type == SNRA_SERVER_CLIENT_SINGLE) { if (client->need_body_complete) soup_message_body_complete (client->event_pipe->response_body); client->need_body_complete = FALSE; soup_server_unpause_message (client->soup, client->event_pipe); } if (client->socket) { soup_socket_disconnect (client->socket); client->socket = NULL; } g_signal_emit (client, snra_server_client_signals[CONNECTION_LOST], 0, NULL); }
static void finalize (GObject *object) { SoupServer *server = SOUP_SERVER (object); SoupServerPrivate *priv = SOUP_SERVER_GET_PRIVATE (server); GSList *iter; if (priv->interface) g_object_unref (priv->interface); g_free (priv->ssl_cert_file); g_free (priv->ssl_key_file); if (priv->ssl_creds) soup_ssl_free_server_credentials (priv->ssl_creds); g_free (priv->server_header); if (priv->listen_sock) g_object_unref (priv->listen_sock); while (priv->client_socks) { SoupSocket *sock = priv->client_socks->data; soup_socket_disconnect (sock); priv->client_socks = g_slist_remove (priv->client_socks, sock); } if (priv->default_handler) free_handler (priv->default_handler); soup_path_map_free (priv->handlers); for (iter = priv->auth_domains; iter; iter = iter->next) g_object_unref (iter->data); g_slist_free (priv->auth_domains); if (priv->loop) g_main_loop_unref (priv->loop); if (priv->async_context) g_main_context_unref (priv->async_context); G_OBJECT_CLASS (soup_server_parent_class)->finalize (object); }
static void request_finished (SoupMessage *msg, SoupClientContext *client) { SoupServer *server = client->server; SoupSocket *sock = client->sock; g_signal_emit (server, msg->status_code == SOUP_STATUS_IO_ERROR ? signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED], 0, msg, client); soup_client_context_cleanup (client); if (soup_socket_is_connected (sock) && soup_message_is_keepalive (msg)) { /* Start a new request */ start_request (server, client); } else { soup_socket_disconnect (sock); soup_client_context_unref (client); } g_object_unref (msg); g_object_unref (sock); }
/** * soup_message_io_stop: * @msg: a #SoupMessage * * Immediately stops I/O on msg; if the connection would be left in an * inconsistent state, it will be closed. * * Note: this is a low-level function that does not cause any signals * to be emitted on @msg; it is up to the caller to make sure that * @msg doesn't get "stranded". **/ void soup_message_io_stop (SoupMessage *msg) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; if (!io) return; if (io->read_tag) { g_signal_handler_disconnect (io->sock, io->read_tag); io->read_tag = 0; } if (io->write_tag) { g_signal_handler_disconnect (io->sock, io->write_tag); io->write_tag = 0; } if (io->err_tag) { g_signal_handler_disconnect (io->sock, io->err_tag); io->err_tag = 0; } if (io->unpause_source) { g_source_destroy (io->unpause_source); io->unpause_source = NULL; } if (io->read_state < SOUP_MESSAGE_IO_STATE_FINISHING) soup_socket_disconnect (io->sock); else if (io->conn) { SoupConnection *conn = io->conn; io->conn = NULL; soup_connection_set_state (conn, SOUP_CONNECTION_IDLE); g_object_unref (conn); } }
static void timeout_socket (SoupSocket *sock, gpointer user_data) { soup_socket_disconnect (sock); }
/** * soup_connection_disconnect: * @conn: a connection * * Disconnects @conn's socket and emits a %disconnected signal. * After calling this, @conn will be essentially useless. **/ void soup_connection_disconnect (SoupConnection *conn) { SoupConnectionPrivate *priv; g_return_if_fail (SOUP_IS_CONNECTION (conn)); priv = SOUP_CONNECTION_GET_PRIVATE (conn); if (!priv->socket) return; g_signal_handlers_disconnect_by_func (priv->socket, socket_disconnected, conn); soup_socket_disconnect (priv->socket); g_object_unref (priv->socket); priv->socket = NULL; /* Don't emit "disconnected" if we aren't yet connected */ if (priv->state < SOUP_CONNECTION_IDLE) return; priv->state = SOUP_CONNECTION_DISCONNECTED; if (priv->cur_req && priv->cur_req->status_code == SOUP_STATUS_IO_ERROR && priv->last_used != 0) { /* There was a message queued on this connection, but * the socket was closed while it was being sent. * Since last_used is not 0, then that means at least * one message was successfully sent on this * connection before, and so the most likely cause of * the IO_ERROR is that the connection was idle for * too long and the server timed out and closed it * (and we didn't notice until after we started * sending the message). So we want the message to get * tried again on a new connection. The only code path * that could have gotten us to this point is through * the call to io_cleanup() in * soup_message_io_finished(), and so all we need to * do to get the message requeued in this case is to * change its status. */ soup_message_cleanup_response (priv->cur_req); soup_message_set_io_status (priv->cur_req, SOUP_MESSAGE_IO_STATUS_QUEUED); } /* If cur_req is non-NULL but priv->last_used is 0, then that * means this was the first message to be sent on this * connection, and it failed, so the error probably means that * there's some network or server problem, so we let the * IO_ERROR be returned to the caller. * * (Of course, it's also possible that the error in the * last_used != 0 case was because of a network/server problem * too. It's even possible that the message crashed the * server. In this case, requeuing it was the wrong thing to * do, but presumably, the next attempt will also get an * error, and eventually the message will be requeued onto a * fresh connection and get an error, at which point the error * will finally be returned to the caller.) */ /* NB: this might cause conn to be destroyed. */ g_signal_emit (conn, signals[DISCONNECTED], 0); }