#include "soup-marshal.h"
#include "soup-message.h"
#include "soup-message-private.h"
+#include "soup-message-queue.h"
#include "soup-misc.h"
#include "soup-socket.h"
#include "soup-ssl.h"
GMainContext *async_context;
- SoupMessage *cur_req;
+ SoupMessageQueueItem *cur_item;
SoupConnectionState state;
time_t unused_timeout;
guint io_timeout, idle_timeout;
GValue *value, GParamSpec *pspec);
static void stop_idle_timer (SoupConnectionPrivate *priv);
-static void clear_current_request (SoupConnection *conn);
+static void clear_current_item (SoupConnection *conn);
/* Number of seconds after which we close a connection that hasn't yet
* been used.
SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
stop_idle_timer (priv);
- /* Make sure clear_current_request doesn't re-establish the timeout */
+ /* Make sure clear_current_item doesn't re-establish the timeout */
priv->idle_timeout = 0;
- if (priv->cur_req) {
- g_warning ("Disposing connection with cur_req set");
- clear_current_request (conn);
+ if (priv->cur_item) {
+ g_warning ("Disposing connection with cur_item set");
+ clear_current_item (conn);
}
if (priv->socket) {
g_warning ("Disposing connection while connected");
g_value_set_enum (value, priv->state);
break;
case PROP_MESSAGE:
- g_value_set_object (value, priv->cur_req);
+ if (priv->cur_item)
+ g_value_set_object (value, priv->cur_item->msg);
+ else
+ g_value_set_object (value, NULL);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
-set_current_request (SoupConnection *conn, SoupMessage *req)
+set_current_item (SoupConnection *conn, SoupMessageQueueItem *item)
{
SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
- g_return_if_fail (priv->cur_req == NULL);
+ g_return_if_fail (priv->cur_item == NULL);
g_object_freeze_notify (G_OBJECT (conn));
stop_idle_timer (priv);
- soup_message_set_io_status (req, SOUP_MESSAGE_IO_STATUS_RUNNING);
- priv->cur_req = req;
+ soup_message_set_io_status (item->msg, SOUP_MESSAGE_IO_STATUS_RUNNING);
+ priv->cur_item = item;
g_object_notify (G_OBJECT (conn), "message");
if (priv->state == SOUP_CONNECTION_IDLE ||
- req->method != SOUP_METHOD_CONNECT)
+ item->msg->method != SOUP_METHOD_CONNECT)
soup_connection_set_state (conn, SOUP_CONNECTION_IN_USE);
g_object_thaw_notify (G_OBJECT (conn));
}
static void
-clear_current_request (SoupConnection *conn)
+clear_current_item (SoupConnection *conn)
{
SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
priv->unused_timeout = 0;
start_idle_timer (conn);
- if (priv->cur_req) {
- SoupMessage *cur_req = priv->cur_req;
- priv->cur_req = NULL;
+ if (priv->cur_item) {
+ SoupMessageQueueItem *item;
+
+ item = priv->cur_item;
+ priv->cur_item = NULL;
g_object_notify (G_OBJECT (conn), "message");
- if (!soup_message_is_keepalive (cur_req))
+ if (item->msg->method == SOUP_METHOD_CONNECT &&
+ SOUP_STATUS_IS_SUCCESSFUL (item->msg->status_code)) {
+ /* We're now effectively no longer proxying */
+ soup_uri_free (priv->proxy_uri);
+ priv->proxy_uri = NULL;
+ }
+
+ if (!soup_message_is_keepalive (item->msg))
soup_connection_disconnect (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);
old_state = priv->state;
priv->state = state;
if ((state == SOUP_CONNECTION_IDLE ||
state == SOUP_CONNECTION_DISCONNECTED) &&
old_state == SOUP_CONNECTION_IN_USE)
- clear_current_request (conn);
+ clear_current_item (conn);
g_object_notify (G_OBJECT (conn), "state");
+ g_object_thaw_notify (G_OBJECT (conn));
}
gboolean
return SOUP_CONNECTION_GET_PRIVATE (conn)->unused_timeout == 0;
}
-/**
- * soup_connection_send_request:
- * @conn: a #SoupConnection
- * @req: a #SoupMessage
- *
- * Sends @req on @conn. This is a low-level function, intended for use
- * by #SoupSession.
- **/
void
-soup_connection_send_request (SoupConnection *conn, SoupMessage *req)
+soup_connection_send_request (SoupConnection *conn,
+ SoupMessageQueueItem *item,
+ SoupMessageCompletionFn completion_cb,
+ gpointer user_data)
{
SoupConnectionPrivate *priv;
g_return_if_fail (SOUP_IS_CONNECTION (conn));
- g_return_if_fail (SOUP_IS_MESSAGE (req));
+ g_return_if_fail (item != NULL);
priv = SOUP_CONNECTION_GET_PRIVATE (conn);
g_return_if_fail (priv->state != SOUP_CONNECTION_NEW && priv->state != SOUP_CONNECTION_DISCONNECTED);
- if (req != priv->cur_req)
- set_current_request (conn, req);
- soup_message_send_request (req, conn);
+ if (item != priv->cur_item)
+ set_current_item (conn, item);
+ soup_message_send_request (item, completion_cb, user_data);
}
#include <gio/gio.h>
#include "soup-types.h"
+#include "soup-message-private.h"
#include "soup-misc.h"
G_BEGIN_DECLS
#define SOUP_IS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SOUP_TYPE_CONNECTION))
#define SOUP_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_CONNECTION, SoupConnectionClass))
-typedef struct {
+struct _SoupConnection {
GObject parent;
-} SoupConnection;
+};
typedef struct {
GObjectClass parent_class;
gboolean soup_connection_get_ever_used (SoupConnection *conn);
-void soup_connection_send_request (SoupConnection *conn,
- SoupMessage *req);
+void soup_connection_send_request (SoupConnection *conn,
+ SoupMessageQueueItem *item,
+ SoupMessageCompletionFn completion_cb,
+ gpointer user_data);
+
G_END_DECLS
#include <stdlib.h>
#include <string.h>
+#include "soup-connection.h"
#include "soup-message-private.h"
#include "soup-auth.h"
#include "soup-connection.h"
#include "soup-headers.h"
+#include "soup-message-queue.h"
#include "soup-uri.h"
static guint
SoupEncoding *encoding, gpointer user_data)
{
SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (req);
- SoupConnection *conn = user_data;
+ SoupMessageQueueItem *item = user_data;
SoupURI *uri = soup_message_get_uri (req);
char *uri_host;
char *uri_string;
/* CONNECT URI is hostname:port for tunnel destination */
uri_string = g_strdup_printf ("%s:%d", uri_host, uri->port);
} else {
- gboolean proxy = soup_connection_is_via_proxy (conn);
+ gboolean proxy = soup_connection_is_via_proxy (item->conn);
/* Proxy expects full URI to destination. Otherwise
* just the path.
}
void
-soup_message_send_request (SoupMessage *msg,
- SoupConnection *conn)
+soup_message_send_request (SoupMessageQueueItem *item,
+ SoupMessageCompletionFn completion_cb,
+ gpointer user_data)
{
- soup_message_cleanup_response (msg);
- soup_message_io_client (msg, conn,
+ soup_message_cleanup_response (item->msg);
+ soup_message_io_client (item,
get_request_headers,
parse_response_headers,
- conn);
+ item,
+ completion_cb, user_data);
}
#include "soup-connection.h"
#include "soup-message.h"
#include "soup-message-private.h"
+#include "soup-message-queue.h"
#include "soup-misc.h"
#include "soup-socket.h"
#include "soup-ssl.h"
typedef struct {
SoupSocket *sock;
- SoupConnection *conn;
+ SoupMessageQueueItem *item;
SoupMessageIOMode mode;
SoupMessageIOState read_state;
SoupMessageGetHeadersFn get_headers_cb;
SoupMessageParseHeadersFn parse_headers_cb;
- gpointer user_data;
+ gpointer header_data;
+ SoupMessageCompletionFn completion_cb;
+ gpointer completion_data;
} SoupMessageIOData;
if (io->sock)
g_object_unref (io->sock);
- if (io->conn)
- g_object_unref (io->conn);
+ if (io->item)
+ soup_message_queue_item_unref (io->item);
g_byte_array_free (io->read_meta_buf, TRUE);
g_slice_free (SoupMessageIOData, io);
}
-/**
- * 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)
{
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);
- }
+ else if (io->item && io->item->conn)
+ soup_connection_set_state (io->item->conn, SOUP_CONNECTION_IDLE);
}
#define SOUP_MESSAGE_IO_EOL "\r\n"
static void
soup_message_io_finished (SoupMessage *msg)
{
+ SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
+ SoupMessageIOData *io = priv->io_data;
+ SoupMessageCompletionFn completion_cb = io->completion_cb;
+ gpointer completion_data = io->completion_data;
+
g_object_ref (msg);
soup_message_io_cleanup (msg);
- if (SOUP_MESSAGE_IS_STARTING (msg))
- soup_message_restarted (msg);
- else
- soup_message_finished (msg);
+ if (completion_cb)
+ completion_cb (msg, completion_data);
g_object_unref (msg);
}
} else if (io->mode == SOUP_MESSAGE_IO_CLIENT &&
io->read_state <= SOUP_MESSAGE_IO_STATE_HEADERS &&
io->read_meta_buf->len == 0 &&
- soup_connection_get_ever_used (io->conn) &&
+ soup_connection_get_ever_used (io->item->conn) &&
!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) &&
request_is_idempotent (msg)) {
/* Connection got closed, but we can safely try again */
if (!io->write_buf->len) {
io->get_headers_cb (msg, io->write_buf,
&io->write_encoding,
- io->user_data);
+ io->header_data);
if (!io->write_buf->len) {
soup_message_io_pause (msg);
return;
status = io->parse_headers_cb (msg, (char *)io->read_meta_buf->data,
io->read_meta_buf->len,
&io->read_encoding,
- io->user_data);
+ io->header_data);
g_byte_array_set_size (io->read_meta_buf, 0);
if (status != SOUP_STATUS_OK) {
new_iostate (SoupMessage *msg, SoupSocket *sock, SoupMessageIOMode mode,
SoupMessageGetHeadersFn get_headers_cb,
SoupMessageParseHeadersFn parse_headers_cb,
- gpointer user_data)
+ gpointer header_data,
+ SoupMessageCompletionFn completion_cb,
+ gpointer completion_data)
{
SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
SoupMessageIOData *io;
io->mode = mode;
io->get_headers_cb = get_headers_cb;
io->parse_headers_cb = parse_headers_cb;
- io->user_data = user_data;
+ io->header_data = header_data;
+ io->completion_cb = completion_cb;
+ io->completion_data = completion_data;
io->read_meta_buf = g_byte_array_new ();
io->write_buf = g_string_new (NULL);
}
void
-soup_message_io_client (SoupMessage *msg, SoupConnection *conn,
+soup_message_io_client (SoupMessageQueueItem *item,
SoupMessageGetHeadersFn get_headers_cb,
SoupMessageParseHeadersFn parse_headers_cb,
- gpointer user_data)
+ gpointer header_data,
+ SoupMessageCompletionFn completion_cb,
+ gpointer completion_data)
{
SoupMessageIOData *io;
- SoupSocket *sock = soup_connection_get_socket (conn);
+ SoupSocket *sock = soup_connection_get_socket (item->conn);
- io = new_iostate (msg, sock, SOUP_MESSAGE_IO_CLIENT,
- get_headers_cb, parse_headers_cb, user_data);
+ io = new_iostate (item->msg, sock, SOUP_MESSAGE_IO_CLIENT,
+ get_headers_cb, parse_headers_cb, header_data,
+ completion_cb, completion_data);
- io->conn = g_object_ref (conn);
+ io->item = item;
+ soup_message_queue_item_ref (item);
- io->read_body = msg->response_body;
- io->write_body = msg->request_body;
+ io->read_body = item->msg->response_body;
+ io->write_body = item->msg->request_body;
io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
- io_write (sock, msg);
+ io_write (sock, item->msg);
}
void
soup_message_io_server (SoupMessage *msg, SoupSocket *sock,
SoupMessageGetHeadersFn get_headers_cb,
SoupMessageParseHeadersFn parse_headers_cb,
- gpointer user_data)
+ gpointer header_data,
+ SoupMessageCompletionFn completion_cb,
+ gpointer completion_data)
{
SoupMessageIOData *io;
io = new_iostate (msg, sock, SOUP_MESSAGE_IO_SERVER,
- get_headers_cb, parse_headers_cb, user_data);
+ get_headers_cb, parse_headers_cb, header_data,
+ completion_cb, completion_data);
io->read_body = msg->request_body;
io->write_body = msg->response_body;
#include "soup-message.h"
#include "soup-auth.h"
-#include "soup-connection.h"
#include "soup-content-sniffer.h"
typedef enum {
} SoupMessagePrivate;
#define SOUP_MESSAGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_MESSAGE, SoupMessagePrivate))
-#define SOUP_MESSAGE_IS_STARTING(msg) (SOUP_MESSAGE_GET_PRIVATE (msg)->io_status == SOUP_MESSAGE_IO_STATUS_QUEUED)
+#define SOUP_MESSAGE_IS_STARTING(msg) (SOUP_MESSAGE_GET_PRIVATE (msg)->io_status == SOUP_MESSAGE_IO_STATUS_QUEUED && !SOUP_STATUS_IS_TRANSPORT_ERROR ((msg)->status_code))
void soup_message_cleanup_response (SoupMessage *req);
guint header_len,
SoupEncoding *encoding,
gpointer user_data);
+typedef void (*SoupMessageCompletionFn) (SoupMessage *msg,
+ gpointer user_data);
+
-void soup_message_send_request (SoupMessage *req,
- SoupConnection *conn);
-void soup_message_read_request (SoupMessage *req,
- SoupSocket *sock);
-
-void soup_message_io_client (SoupMessage *msg,
- SoupConnection *conn,
- SoupMessageGetHeadersFn get_headers_cb,
- SoupMessageParseHeadersFn parse_headers_cb,
- gpointer user_data);
-void soup_message_io_server (SoupMessage *msg,
- SoupSocket *sock,
- SoupMessageGetHeadersFn get_headers_cb,
- SoupMessageParseHeadersFn parse_headers_cb,
- gpointer user_data);
-void soup_message_io_cleanup (SoupMessage *msg);
+void soup_message_send_request (SoupMessageQueueItem *item,
+ SoupMessageCompletionFn completion_cb,
+ gpointer user_data);
+void soup_message_read_request (SoupMessage *req,
+ SoupSocket *sock,
+ SoupMessageCompletionFn completion_cb,
+ gpointer user_data);
+
+void soup_message_io_client (SoupMessageQueueItem *item,
+ SoupMessageGetHeadersFn get_headers_cb,
+ SoupMessageParseHeadersFn parse_headers_cb,
+ gpointer headers_data,
+ SoupMessageCompletionFn completion_cb,
+ gpointer user_data);
+void soup_message_io_server (SoupMessage *msg,
+ SoupSocket *sock,
+ SoupMessageGetHeadersFn get_headers_cb,
+ SoupMessageParseHeadersFn parse_headers_cb,
+ gpointer headers_data,
+ SoupMessageCompletionFn completion_cb,
+ gpointer user_data);
+void soup_message_io_cleanup (SoupMessage *msg);
/* Auth handling */
void soup_message_set_auth (SoupMessage *msg,
* "removed" ones when walking the queue.
**/
-struct SoupMessageQueue {
+struct _SoupMessageQueue {
SoupSession *session;
GMutex *mutex;
#include <glib.h>
#include <gio/gio.h>
-#include <libsoup/soup-connection.h>
-#include <libsoup/soup-message.h>
-#include <libsoup/soup-session.h>
-G_BEGIN_DECLS
+#include "soup-connection.h"
+#include "soup-message.h"
+#include "soup-session.h"
-typedef struct SoupMessageQueue SoupMessageQueue;
-typedef struct SoupMessageQueueItem SoupMessageQueueItem;
+G_BEGIN_DECLS
-struct SoupMessageQueueItem {
+struct _SoupMessageQueueItem {
/*< public >*/
SoupSession *session;
SoupMessageQueue *queue;
}
void
-soup_message_read_request (SoupMessage *req, SoupSocket *sock)
+soup_message_read_request (SoupMessage *msg,
+ SoupSocket *sock,
+ SoupMessageCompletionFn completion_cb,
+ gpointer user_data)
{
- soup_message_io_server (req, sock,
+ soup_message_io_server (msg, sock,
get_response_headers,
parse_request_headers,
- sock);
+ sock,
+ completion_cb, user_data);
}
}
static void
-request_finished (SoupMessage *msg, SoupClientContext *client)
+request_finished (SoupMessage *msg, gpointer user_data)
{
+ SoupClientContext *client = user_data;
SoupServer *server = client->server;
SoupSocket *sock = client->sock;
+ soup_message_finished (msg);
g_signal_emit (server,
msg->status_code == SOUP_STATUS_IO_ERROR ?
signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED],
g_signal_connect (msg, "got_headers", G_CALLBACK (got_headers), client);
g_signal_connect (msg, "got_body", G_CALLBACK (call_handler), client);
- g_signal_connect (msg, "finished", G_CALLBACK (request_finished), client);
g_signal_emit (server, signals[REQUEST_STARTED], 0,
msg, client);
g_object_ref (client->sock);
- soup_message_read_request (msg, client->sock);
+ soup_message_read_request (msg, client->sock,
+ request_finished, client);
}
static void
#include "soup-session-private.h"
#include "soup-address.h"
#include "soup-message-private.h"
+#include "soup-message-queue.h"
#include "soup-misc.h"
#include "soup-password-manager.h"
#include "soup-proxy-uri-resolver.h"
}
static void
+tunnel_message_completed (SoupMessage *msg, gpointer user_data)
+{
+ SoupMessageQueueItem *item = user_data;
+
+ if (SOUP_MESSAGE_IS_STARTING (msg)) {
+ soup_message_restarted (msg);
+ if (soup_connection_get_state (item->conn) != SOUP_CONNECTION_DISCONNECTED) {
+ soup_session_send_queue_item (item->session, item, item->conn, tunnel_message_completed);
+ return;
+ }
+
+ soup_message_set_status (msg, SOUP_STATUS_TRY_AGAIN);
+ }
+
+ soup_message_finished (msg);
+}
+
+static void
tunnel_connected (SoupMessage *msg, gpointer user_data)
{
SoupMessageQueueItem *item = user_data;
}
static void
-tunnel_connect_restarted (SoupMessage *msg, gpointer user_data)
-{
- SoupMessageQueueItem *item = user_data;
-
- if (SOUP_MESSAGE_IS_STARTING (msg))
- soup_session_send_queue_item (item->session, item, item->conn);
-}
-
-static void
got_connection (SoupConnection *conn, guint status, gpointer user_data)
{
SoupSession *session = user_data;
g_signal_emit_by_name (session, "tunneling", conn);
g_signal_connect (item->msg, "finished",
G_CALLBACK (tunnel_connected), item);
- g_signal_connect (item->msg, "restarted",
- G_CALLBACK (tunnel_connect_restarted), item);
- soup_session_send_queue_item (session, item, conn);
+ soup_session_send_queue_item (session, item, conn, tunnel_message_completed);
return;
}
}
static void
+message_completed (SoupMessage *msg, gpointer user_data)
+{
+ if (SOUP_MESSAGE_IS_STARTING (msg))
+ soup_message_restarted (msg);
+ else
+ soup_message_finished (msg);
+}
+
+static void
run_queue (SoupSessionAsync *sa)
{
SoupSession *session = SOUP_SESSION (sa);
got_connection,
g_object_ref (session));
} else
- soup_session_send_queue_item (session, item, conn);
+ soup_session_send_queue_item (session, item, conn, message_completed);
}
if (item)
soup_message_queue_item_unref (item);
#define SOUP_SESSION_PRIVATE_H 1
#include "soup-session.h"
-#include "soup-connection.h"
-#include "soup-message-queue.h"
+#include "soup-message-private.h"
#include "soup-proxy-uri-resolver.h"
G_BEGIN_DECLS
void soup_session_send_queue_item (SoupSession *session,
SoupMessageQueueItem *item,
- SoupConnection *conn);
+ SoupConnection *conn,
+ SoupMessageCompletionFn completion_cb);
G_END_DECLS
#include "soup-session-private.h"
#include "soup-address.h"
#include "soup-message-private.h"
+#include "soup-message-queue.h"
#include "soup-misc.h"
#include "soup-password-manager.h"
#include "soup-proxy-uri-resolver.h"
g_signal_emit_by_name (session, "tunneling", conn);
item = soup_session_make_connect_message (session, tunnel_addr);
- do
- soup_session_send_queue_item (session, item, conn);
- while (SOUP_MESSAGE_IS_STARTING (item->msg));
-
- status = item->msg->status_code;
+ do {
+ soup_session_send_queue_item (session, item, conn, NULL);
+ if (SOUP_MESSAGE_IS_STARTING (item->msg))
+ soup_message_restarted (item->msg) ;
+ else
+ soup_message_finished (item->msg);
+ } while (SOUP_MESSAGE_IS_STARTING (item->msg) &&
+ soup_connection_get_state (conn) != SOUP_CONNECTION_DISCONNECTED);
+
+ /* If the message was requeued but its connection was closed,
+ * return TRY_AGAIN to our caller.
+ */
+ if (SOUP_MESSAGE_IS_STARTING (item->msg))
+ status = SOUP_STATUS_TRY_AGAIN;
+ else
+ status = item->msg->status_code;
soup_message_queue_item_unref (item);
if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
status = tunnel_connect (session, conn, tunnel_addr);
if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
conn = NULL;
- goto try_again;
+ if (status == SOUP_STATUS_TRY_AGAIN)
+ goto try_again;
}
}
}
if (!conn)
break;
- soup_session_send_queue_item (item->session, item, conn);
+ soup_session_send_queue_item (item->session, item, conn, NULL);
+ if (SOUP_MESSAGE_IS_STARTING (item->msg))
+ soup_message_restarted (item->msg);
+ else
+ soup_message_finished (item->msg);
g_cond_broadcast (priv->cond);
} while (soup_message_get_io_status (item->msg) !=
SOUP_MESSAGE_IO_STATUS_FINISHED);
void
soup_session_send_queue_item (SoupSession *session,
SoupMessageQueueItem *item,
- SoupConnection *conn)
+ SoupConnection *conn,
+ SoupMessageCompletionFn completion_cb)
{
SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
g_signal_emit (session, signals[REQUEST_STARTED], 0,
item->msg, soup_connection_get_socket (conn));
- soup_connection_send_request (conn, item->msg);
+ soup_connection_send_request (conn, item, completion_cb, item);
}
gboolean
g_object_unref (session);
}
-static void
-tunnel_connected (SoupMessage *msg, gpointer user_data)
-{
- SoupSession *session = user_data;
-
- if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
- SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
- SoupMessageQueueItem *item =
- soup_message_queue_lookup (priv->queue, msg);
-
- /* Clear the connection's proxy_uri, since it is now
- * (effectively) directly connected.
- */
- g_object_set (item->conn,
- SOUP_CONNECTION_PROXY_URI, NULL,
- NULL);
- soup_message_queue_item_unref (item);
- }
-}
-
-static void
-tunnel_connect_restarted (SoupMessage *msg, gpointer session)
-{
- SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
- SoupMessageQueueItem *item;
-
- if (msg->status_code != SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED)
- return;
-
- item = soup_message_queue_lookup (priv->queue, msg);
- if (!item)
- return;
- if (soup_connection_get_state (item->conn) == SOUP_CONNECTION_DISCONNECTED) {
- /* We got a 407, and the session provided auth and
- * restarted the message, but the proxy closed the
- * connection, so we need to create a new one. The
- * easiest way to do this is to just give up on the
- * current msg and conn, and re-run the queue.
- */
- soup_session_cancel_message (session, msg,
- SOUP_STATUS_TRY_AGAIN);
- }
- soup_message_queue_item_unref (item);
-}
-
SoupMessageQueueItem *
soup_session_make_connect_message (SoupSession *session,
SoupAddress *server_addr)
/* Call the base implementation of soup_session_queue_message
* directly, to add msg to the SoupMessageQueue and cause all
- * the right signals to be emitted. We can't use
- * queue_message's callback arg in this case because that's
- * actually implemented by the subclasses.
+ * the right signals to be emitted.
*/
- g_signal_connect (msg, "finished",
- G_CALLBACK (tunnel_connected), session);
- g_signal_connect (msg, "restarted",
- G_CALLBACK (tunnel_connect_restarted), session);
queue_message (session, msg, NULL, NULL);
item = soup_message_queue_lookup (priv->queue, msg);
g_object_unref (msg);
typedef struct _SoupSocket SoupSocket;
typedef struct _SoupURI SoupURI;
+/*< private >*/
+typedef struct _SoupConnection SoupConnection;
+typedef struct _SoupMessageQueue SoupMessageQueue;
+typedef struct _SoupMessageQueueItem SoupMessageQueueItem;
+
G_END_DECLS
#endif