Exemple #1
0
/**
 * 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);
}
Exemple #2
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);
}
Exemple #4
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);
}
Exemple #5
0
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);
	}
}
Exemple #9
0
static void
timeout_socket (SoupSocket *sock, gpointer user_data)
{
	soup_socket_disconnect (sock);
}
Exemple #10
0
/**
 * 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);
}