[libsoup] soup-message-io: add soup_message_io_steal()
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup] soup-message-io: add soup_message_io_steal()
- Date: Sun, 1 Mar 2015 15:39:06 +0000 (UTC)
commit 0ebeb24f7935729deb29acc54b59b4af8fec09e1
Author: Dan Winship <danw gnome org>
Date: Wed Dec 10 15:36:55 2014 +0100
soup-message-io: add soup_message_io_steal()
Add a method to allow a GIOStream to be stolen from the I/O system
mid-request.
libsoup/soup-message-io.c | 50 ++++++++++++++++++++++++++++++++++++---
libsoup/soup-message-private.h | 21 +++++++++++-----
libsoup/soup-server.c | 14 ++++++----
libsoup/soup-session.c | 5 ++-
4 files changed, 71 insertions(+), 19 deletions(-)
---
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index 4629568..021a5ec 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -156,7 +156,7 @@ soup_message_io_finished (SoupMessage *msg)
SoupMessageIOData *io = priv->io_data;
SoupMessageCompletionFn completion_cb;
gpointer completion_data;
- gboolean complete;
+ SoupMessageIOCompletion completion;
if (!io)
return;
@@ -164,16 +164,44 @@ soup_message_io_finished (SoupMessage *msg)
completion_cb = io->completion_cb;
completion_data = io->completion_data;
- complete = (io->read_state >= SOUP_MESSAGE_IO_STATE_FINISHING &&
- io->write_state >= SOUP_MESSAGE_IO_STATE_FINISHING);
+ if ((io->read_state >= SOUP_MESSAGE_IO_STATE_FINISHING &&
+ io->write_state >= SOUP_MESSAGE_IO_STATE_FINISHING))
+ completion = SOUP_MESSAGE_IO_COMPLETE;
+ else
+ completion = SOUP_MESSAGE_IO_INTERRUPTED;
g_object_ref (msg);
soup_message_io_cleanup (msg);
if (completion_cb)
- completion_cb (msg, complete, completion_data);
+ completion_cb (msg, completion, completion_data);
g_object_unref (msg);
}
+GIOStream *
+soup_message_io_steal (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg);
+ SoupMessageIOData *io = priv->io_data;
+ SoupMessageCompletionFn completion_cb;
+ gpointer completion_data;
+ GIOStream *iostream;
+
+ if (!io || !io->iostream)
+ return NULL;
+
+ iostream = g_object_ref (io->iostream);
+ completion_cb = io->completion_cb;
+ completion_data = io->completion_data;
+
+ g_object_ref (msg);
+ soup_message_io_cleanup (msg);
+ if (completion_cb)
+ completion_cb (msg, SOUP_MESSAGE_IO_STOLEN, completion_data);
+ g_object_unref (msg);
+
+ return iostream;
+}
+
static gboolean
read_headers (SoupMessage *msg, gboolean blocking,
GCancellable *cancellable, GError **error)
@@ -407,6 +435,13 @@ io_write (SoupMessage *msg, gboolean blocking,
}
soup_message_wrote_informational (msg);
+
+ /* If this was "101 Switching Protocols", then
+ * the server probably stole the connection...
+ */
+ if (io != priv->io_data)
+ return FALSE;
+
soup_message_cleanup_response (msg);
break;
}
@@ -611,6 +646,13 @@ io_read (SoupMessage *msg, gboolean blocking,
* bail out here rather than parsing encoding, etc
*/
soup_message_got_informational (msg);
+
+ /* If this was "101 Switching Protocols", then
+ * the session may have stolen the connection...
+ */
+ if (io != priv->io_data)
+ return FALSE;
+
soup_message_cleanup_response (msg);
break;
} else if (io->mode == SOUP_MESSAGE_IO_SERVER &&
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index 9860dee..a9457bc 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -48,6 +48,11 @@ typedef struct {
void soup_message_cleanup_response (SoupMessage *msg);
+typedef enum {
+ SOUP_MESSAGE_IO_COMPLETE,
+ SOUP_MESSAGE_IO_INTERRUPTED,
+ SOUP_MESSAGE_IO_STOLEN
+} SoupMessageIOCompletion;
typedef void (*SoupMessageGetHeadersFn) (SoupMessage *msg,
GString *headers,
@@ -60,7 +65,7 @@ typedef guint (*SoupMessageParseHeadersFn)(SoupMessage *msg,
gpointer user_data,
GError **error);
typedef void (*SoupMessageCompletionFn) (SoupMessage *msg,
- gboolean io_complete,
+ SoupMessageIOCompletion completion,
gpointer user_data);
@@ -89,7 +94,6 @@ void soup_message_io_server (SoupMessage *msg,
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,
@@ -100,11 +104,14 @@ void soup_message_set_proxy_auth (SoupMessage *msg,
SoupAuth *soup_message_get_proxy_auth (SoupMessage *msg);
/* I/O */
-void soup_message_io_stop (SoupMessage *msg);
-void soup_message_io_finished (SoupMessage *msg);
-void soup_message_io_pause (SoupMessage *msg);
-void soup_message_io_unpause (SoupMessage *msg);
-gboolean soup_message_io_in_progress (SoupMessage *msg);
+void soup_message_io_stop (SoupMessage *msg);
+void soup_message_io_finished (SoupMessage *msg);
+void soup_message_io_cleanup (SoupMessage *msg);
+void soup_message_io_pause (SoupMessage *msg);
+void soup_message_io_unpause (SoupMessage *msg);
+gboolean soup_message_io_in_progress (SoupMessage *msg);
+GIOStream *soup_message_io_steal (SoupMessage *msg);
+
gboolean soup_message_io_run_until_write (SoupMessage *msg,
gboolean blocking,
diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c
index 65957b9..7c85532 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -1159,23 +1159,26 @@ soup_client_context_unref (SoupClientContext *client)
}
static void
-request_finished (SoupMessage *msg, gboolean io_complete, gpointer user_data)
+request_finished (SoupMessage *msg, SoupMessageIOCompletion completion, gpointer user_data)
{
SoupClientContext *client = user_data;
SoupServer *server = client->server;
SoupSocket *sock = client->sock;
+ gboolean failed;
soup_message_finished (msg);
+ failed = (completion == SOUP_MESSAGE_IO_INTERRUPTED ||
+ msg->status_code == SOUP_STATUS_IO_ERROR);
g_signal_emit (server,
- (!io_complete || msg->status_code == SOUP_STATUS_IO_ERROR) ?
- signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED],
+ failed ? signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED],
0, msg, client);
- soup_client_context_cleanup (client);
- if (io_complete && soup_socket_is_connected (sock) &&
+ if (completion == SOUP_MESSAGE_IO_COMPLETE &&
+ soup_socket_is_connected (sock) &&
soup_message_is_keepalive (msg)) {
/* Start a new request */
+ soup_client_context_cleanup (client);
start_request (server, client);
} else {
soup_socket_disconnect (sock);
@@ -2600,4 +2603,3 @@ soup_server_unpause_message (SoupServer *server,
soup_message_io_unpause (msg);
}
-
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 377d420..77756c1 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -1570,7 +1570,7 @@ soup_session_set_item_status (SoupSession *session,
static void
-message_completed (SoupMessage *msg, gboolean io_complete, gpointer user_data)
+message_completed (SoupMessage *msg, SoupMessageIOCompletion completion, gpointer user_data)
{
SoupMessageQueueItem *item = user_data;
@@ -1676,7 +1676,8 @@ tunnel_handshake_complete (GObject *object,
}
static void
-tunnel_message_completed (SoupMessage *msg, gboolean io_complete, gpointer user_data)
+tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion,
+ gpointer user_data)
{
SoupMessageQueueItem *tunnel_item = user_data;
SoupMessageQueueItem *item = tunnel_item->related;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]