[libsoup/wip/http2-upstreaming: 1/2] Turn soup-message-io into an interface
- From: Patrick Griffis <pgriffis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/wip/http2-upstreaming: 1/2] Turn soup-message-io into an interface
- Date: Wed, 14 Apr 2021 18:19:33 +0000 (UTC)
commit a61d6a9d3fad6795c5fb3cd990328817dce96fb8
Author: Patrick Griffis <pgriffis igalia com>
Date: Fri Nov 20 14:45:26 2020 -0600
Turn soup-message-io into an interface
This allows abstracting over http1 and http2
docs/reference/meson.build | 1 +
libsoup/meson.build | 3 +-
libsoup/server/soup-server-io.c | 1 +
libsoup/soup-connection.c | 6 +-
libsoup/soup-logger-private.h | 2 +-
libsoup/soup-logger.c | 9 +-
libsoup/soup-message-io-backend.c | 168 +++++++++++
libsoup/soup-message-io-backend.h | 100 +++++++
libsoup/soup-message-io-data.c | 2 +-
libsoup/soup-message-io-data.h | 11 +-
.../{soup-message-io.c => soup-message-io-http1.c} | 320 +++++++++++----------
libsoup/soup-message-io-http1.h | 33 +++
libsoup/soup-message-private.h | 54 +---
libsoup/soup-message.c | 68 ++++-
14 files changed, 545 insertions(+), 233 deletions(-)
---
diff --git a/docs/reference/meson.build b/docs/reference/meson.build
index de67bb20..c8ce6e59 100644
--- a/docs/reference/meson.build
+++ b/docs/reference/meson.build
@@ -34,6 +34,7 @@ ignore_headers = [
'soup-private-enum-types.h',
'soup-server-message-private.h',
'soup-message-io-data.h',
+ 'soup-message-io-http1.h',
'soup-uri-utils-private.h',
'soup-session-feature-private.h',
'soup-message-metrics-private.h',
diff --git a/libsoup/meson.build b/libsoup/meson.build
index adcccc3e..629962b3 100644
--- a/libsoup/meson.build
+++ b/libsoup/meson.build
@@ -62,7 +62,8 @@ soup_sources = [
'soup-logger-input-stream.c',
'soup-message.c',
'soup-message-headers.c',
- 'soup-message-io.c',
+ 'soup-message-io-backend.c',
+ 'soup-message-io-http1.c',
'soup-message-io-data.c',
'soup-message-metrics.c',
'soup-message-queue-item.c',
diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c
index a806d2f3..45c22bf8 100644
--- a/libsoup/server/soup-server-io.c
+++ b/libsoup/server/soup-server-io.c
@@ -15,6 +15,7 @@
#include "soup-body-input-stream.h"
#include "soup-body-output-stream.h"
#include "soup-filter-input-stream.h"
+#include "soup-message-io-backend.h"
#include "soup-server-message-private.h"
#include "soup-misc.h"
#include "soup-socket.h"
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 4beb599b..71f0dcf9 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -13,6 +13,7 @@
#include "soup.h"
#include "soup-io-stream.h"
#include "soup-message-queue-item.h"
+#include "soup-message-io-http1.h"
#include "soup-socket-properties.h"
#include "soup-private-enum-types.h"
#include <gio/gnetworking.h>
@@ -1067,7 +1068,10 @@ soup_connection_send_request (SoupConnection *conn,
else
priv->reusable = FALSE;
- soup_message_send_request (item, completion_cb, user_data);
+ SoupMessageIOHTTP1 *http1 = soup_message_io_http1_new ();
+ soup_message_set_io_data (item->msg, SOUP_MESSAGE_IO_BACKEND (http1));
+ soup_message_io_backend_send_item (SOUP_MESSAGE_IO_BACKEND (http1),
+ item, completion_cb, user_data);
}
GTlsCertificate *
diff --git a/libsoup/soup-logger-private.h b/libsoup/soup-logger-private.h
index 8307319a..23de245c 100644
--- a/libsoup/soup-logger-private.h
+++ b/libsoup/soup-logger-private.h
@@ -9,6 +9,6 @@
G_BEGIN_DECLS
-void soup_logger_request_body_setup (SoupLogger *logger, SoupMessage *msg);
+void soup_logger_request_body_setup (SoupLogger *logger, SoupMessage *msg, SoupBodyOutputStream *stream);
G_END_DECLS
diff --git a/libsoup/soup-logger.c b/libsoup/soup-logger.c
index c9899e22..39cee2a1 100644
--- a/libsoup/soup-logger.c
+++ b/libsoup/soup-logger.c
@@ -841,16 +841,15 @@ body_ostream_done (gpointer data, GObject *bostream)
}
void
-soup_logger_request_body_setup (SoupLogger *logger, SoupMessage *msg)
+soup_logger_request_body_setup (SoupLogger *logger, SoupMessage *msg, SoupBodyOutputStream *stream)
{
SoupLoggerPrivate *priv = soup_logger_get_instance_private (logger);
- SoupMessageIOData *io = (SoupMessageIOData *)soup_message_get_io_data (msg);
- g_hash_table_insert (priv->request_messages, io->body_ostream, msg);
- g_signal_connect_object (io->body_ostream, "wrote-data",
+ g_hash_table_insert (priv->request_messages, stream, msg);
+ g_signal_connect_object (stream, "wrote-data",
G_CALLBACK (body_stream_wrote_data_cb),
logger, 0);
- g_object_weak_ref (G_OBJECT (io->body_ostream), body_ostream_done, priv);
+ g_object_weak_ref (G_OBJECT (stream), body_ostream_done, priv);
}
static void
diff --git a/libsoup/soup-message-io-backend.c b/libsoup/soup-message-io-backend.c
new file mode 100644
index 00000000..cdabd224
--- /dev/null
+++ b/libsoup/soup-message-io-backend.c
@@ -0,0 +1,168 @@
+/* soup-message-io-backend.c
+ *
+ * Copyright 2020 Igalia S.L.
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ */
+
+#include "config.h"
+
+#include "soup-message-io-backend.h"
+#include "soup-message-private.h"
+
+G_DEFINE_INTERFACE (SoupMessageIOBackend, soup_message_io_backend, G_TYPE_OBJECT)
+
+void
+soup_message_io_run (SoupMessage *msg,
+ gboolean blocking)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ if (backend) {
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ iface->run (msg, blocking);
+ }
+}
+
+void
+soup_message_io_finished (SoupMessage *msg)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ if (backend) {
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ iface->finished (msg);
+ }
+}
+
+void
+soup_message_io_pause (SoupMessage *msg)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ if (backend) {
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ iface->pause (msg);
+ }
+}
+
+void
+soup_message_io_unpause (SoupMessage *msg)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ if (backend) {
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ iface->unpause (msg);
+ }
+}
+
+void
+soup_message_io_stolen (SoupMessage *msg)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ if (backend) {
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ iface->stolen (msg);
+ }
+}
+
+gboolean
+soup_message_io_in_progress (SoupMessage *msg)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ if (backend) {
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ return iface->in_progress (msg);
+ }
+ return FALSE;
+}
+
+gboolean
+soup_message_io_is_paused (SoupMessage *msg)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ if (backend) {
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ return iface->is_paused (msg);
+ }
+ return FALSE;
+}
+
+GInputStream *
+soup_message_io_get_response_istream (SoupMessage *msg,
+ GError **error)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ return iface->get_response_istream (msg, error);
+}
+
+gboolean
+soup_message_io_run_until_read (SoupMessage *msg,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ return iface->run_until_read (msg, cancellable, error);
+}
+
+gboolean
+soup_message_io_run_until_finish (SoupMessage *msg,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ return iface->run_until_finish (msg, blocking, cancellable, error);
+}
+
+void
+soup_message_io_run_until_read_async (SoupMessage *msg,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SoupMessageIOBackend *backend = soup_message_get_io_data (msg);
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ iface->run_until_read_async (msg, io_priority, cancellable, callback, user_data);
+}
+
+gboolean
+soup_message_io_run_until_read_finish (SoupMessage *msg,
+ GAsyncResult *result,
+ GError **error)
+{
+ /* For now just assume all implemenations use GTask the same way as
+ it simplifies the lifecycle of the backend being destroyed before the
+ task returns */
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+void
+soup_message_io_backend_send_item (SoupMessageIOBackend *backend,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data)
+{
+ SoupMessageIOBackendInterface *iface = SOUP_MESSAGE_IO_BACKEND_GET_IFACE (backend);
+ iface->send_item (backend, item, completion_cb, user_data);
+}
+
+
+static void
+soup_message_io_backend_default_init (SoupMessageIOBackendInterface *iface)
+{
+}
\ No newline at end of file
diff --git a/libsoup/soup-message-io-backend.h b/libsoup/soup-message-io-backend.h
new file mode 100644
index 00000000..a43dc5bd
--- /dev/null
+++ b/libsoup/soup-message-io-backend.h
@@ -0,0 +1,100 @@
+/* soup-message-io-backend.h
+ *
+ * Copyright 2020 Igalia S.L.
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "soup-types.h"
+#include "soup-message-headers.h"
+#include "soup-filter-input-stream.h"
+
+G_BEGIN_DECLS
+
+#define SOUP_TYPE_MESSAGE_IO_BACKEND (soup_message_io_backend_get_type ())
+
+G_DECLARE_INTERFACE (SoupMessageIOBackend, soup_message_io_backend, SOUP, MESSAGE_IO_BACKEND, GObject)
+
+typedef gboolean (*SoupMessageSourceFunc) (SoupMessage *, gpointer);
+
+typedef enum {
+ SOUP_MESSAGE_IO_COMPLETE,
+ SOUP_MESSAGE_IO_INTERRUPTED,
+ SOUP_MESSAGE_IO_STOLEN
+} SoupMessageIOCompletion;
+
+typedef void (*SoupMessageIOCompletionFn) (GObject *msg,
+ SoupMessageIOCompletion completion,
+ gpointer user_data);
+
+struct _SoupMessageIOBackendInterface
+{
+ GTypeInterface parent;
+
+ void (*finished) (SoupMessage *);
+ void (*cleanup) (SoupMessage *);
+ void (*pause) (SoupMessage *);
+ void (*unpause) (SoupMessage *);
+ void (*stolen) (SoupMessage *);
+ gboolean (*is_paused) (SoupMessage *);
+ gboolean (*in_progress) (SoupMessage *);
+ GSource * (*get_source) (SoupMessage *, GCancellable *, SoupMessageSourceFunc, gpointer);
+ GInputStream * (*get_response_istream) (SoupMessage *, GError **);
+ void (*run) (SoupMessage *, gboolean);
+ gboolean (*run_until_read) (SoupMessage *, GCancellable *, GError **);
+ gboolean (*run_until_finish) (SoupMessage *, gboolean, GCancellable *, GError **);
+ void (*run_until_read_async) (SoupMessage *, int, GCancellable *, GAsyncReadyCallback, gpointer);
+ void (*send_item) (SoupMessageIOBackend *, SoupMessageQueueItem *, SoupMessageIOCompletionFn,
gpointer);
+};
+
+void soup_message_io_finished (SoupMessage *msg);
+void soup_message_io_pause (SoupMessage *msg);
+void soup_message_io_unpause (SoupMessage *msg);
+void soup_message_io_stolen (SoupMessage *msg);
+gboolean soup_message_io_in_progress (SoupMessage *msg);
+gboolean soup_message_io_is_paused (SoupMessage *msg);
+
+void soup_message_io_run (SoupMessage *msg,
+ gboolean blocking);
+
+gboolean soup_message_io_run_until_read (SoupMessage *msg,
+ GCancellable *cancellable,
+ GError **error);
+void soup_message_io_run_until_read_async (SoupMessage *msg,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean soup_message_io_run_until_read_finish (SoupMessage *msg,
+ GAsyncResult *result,
+ GError **error);
+
+gboolean soup_message_io_run_until_finish (SoupMessage *msg,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error);
+
+GInputStream *soup_message_io_get_response_istream (SoupMessage *msg,
+ GError **error);
+
+void soup_message_io_backend_send_item (SoupMessageIOBackend *backend,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data);
+
+G_END_DECLS
\ No newline at end of file
diff --git a/libsoup/soup-message-io-data.c b/libsoup/soup-message-io-data.c
index 04a9c255..87026633 100644
--- a/libsoup/soup-message-io-data.c
+++ b/libsoup/soup-message-io-data.c
@@ -116,7 +116,7 @@ static gboolean
message_io_is_paused (GObject *msg)
{
if (SOUP_IS_MESSAGE (msg))
- return soup_message_is_io_paused (SOUP_MESSAGE (msg));
+ return soup_message_io_is_paused (SOUP_MESSAGE (msg));
if (SOUP_IS_SERVER_MESSAGE (msg))
return soup_server_message_is_io_paused (SOUP_SERVER_MESSAGE (msg));
diff --git a/libsoup/soup-message-io-data.h b/libsoup/soup-message-io-data.h
index e3feae7a..0f317385 100644
--- a/libsoup/soup-message-io-data.h
+++ b/libsoup/soup-message-io-data.h
@@ -8,6 +8,7 @@
#include "soup-filter-input-stream.h"
#include "soup-message-headers.h"
+#include "soup-message-io-backend.h"
typedef enum {
SOUP_MESSAGE_IO_STATE_NOT_STARTED,
@@ -31,16 +32,6 @@ typedef enum {
(SOUP_MESSAGE_IO_STATE_ACTIVE (state) && \
state != SOUP_MESSAGE_IO_STATE_BODY_DONE)
-typedef enum {
- SOUP_MESSAGE_IO_COMPLETE,
- SOUP_MESSAGE_IO_INTERRUPTED,
- SOUP_MESSAGE_IO_STOLEN
-} SoupMessageIOCompletion;
-
-typedef void (*SoupMessageIOCompletionFn) (GObject *msg,
- SoupMessageIOCompletion completion,
- gpointer user_data);
-
typedef struct {
GIOStream *iostream;
SoupFilterInputStream *istream;
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io-http1.c
similarity index 82%
rename from libsoup/soup-message-io.c
rename to libsoup/soup-message-io-http1.c
index 68b437e5..cc43bbf6 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io-http1.c
@@ -3,6 +3,22 @@
* soup-message-io.c: HTTP message I/O
*
* Copyright (C) 2000-2003, Ximian, Inc.
+ * Copyright 2020 Igalia S.L.
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifdef HAVE_CONFIG_H
@@ -15,6 +31,8 @@
#include <sysprof-capture.h>
#endif
+#include "soup-message-io-http1.h"
+
#include "soup.h"
#include "soup-body-input-stream.h"
#include "soup-body-output-stream.h"
@@ -30,8 +48,9 @@
#include "soup-misc.h"
#include "soup-uri-utils-private.h"
-struct _SoupClientMessageIOData {
- SoupMessageIOData base;
+struct _SoupMessageIOHTTP1 {
+ GObject parent_instance;
+ SoupMessageIOData base;
SoupMessageQueueItem *item;
@@ -42,23 +61,16 @@ struct _SoupClientMessageIOData {
#endif
};
-#define RESPONSE_BLOCK_SIZE 8192
-#define HEADER_SIZE_LIMIT (64 * 1024)
-
-void
-soup_client_message_io_data_free (SoupClientMessageIOData *io)
-{
- if (!io)
- return;
+static void soup_message_io_http1_iface_init (SoupMessageIOBackendInterface *);
- soup_message_io_data_cleanup (&io->base);
- soup_message_queue_item_unref (io->item);
+G_DEFINE_TYPE_WITH_CODE (SoupMessageIOHTTP1, soup_message_io_http1, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (SOUP_TYPE_MESSAGE_IO_BACKEND,
soup_message_io_http1_iface_init))
- g_slice_free (SoupClientMessageIOData, io);
-}
+#define RESPONSE_BLOCK_SIZE 8192
+#define HEADER_SIZE_LIMIT (64 * 1024)
static int
-soup_client_message_io_data_get_priority (SoupClientMessageIOData *io)
+soup_client_message_io_data_get_priority (SoupMessageIOHTTP1 *io)
{
if (!io->item->task)
return G_PRIORITY_DEFAULT;
@@ -66,15 +78,21 @@ soup_client_message_io_data_get_priority (SoupClientMessageIOData *io)
return g_task_get_priority (io->item->task);
}
-void
-soup_message_io_finished (SoupMessage *msg)
+static SoupMessageIOHTTP1 *
+get_io_data (SoupMessage *msg)
{
- SoupClientMessageIOData *io;
+ return SOUP_MESSAGE_IO_HTTP1 (soup_message_get_io_data (msg));
+}
+
+static void
+soup_message_io_http1_finished (SoupMessage *msg)
+{
+ SoupMessageIOHTTP1 *io;
SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
SoupMessageIOCompletion completion;
- io = soup_message_get_io_data (msg);
+ io = get_io_data (msg);
if (!io)
return;
@@ -88,89 +106,36 @@ soup_message_io_finished (SoupMessage *msg)
completion = SOUP_MESSAGE_IO_INTERRUPTED;
g_object_ref (msg);
- soup_message_set_io_data (msg, NULL);
+ soup_message_clear_io_data (msg);
if (completion_cb)
completion_cb (G_OBJECT (msg), completion, completion_data);
g_object_unref (msg);
}
-void
-soup_message_io_stolen (SoupMessage *msg)
+static void
+soup_message_io_http1_stolen (SoupMessage *msg)
{
- SoupClientMessageIOData *io;
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
- io = soup_message_get_io_data (msg);
- if (!io)
- return;
-
completion_cb = io->base.completion_cb;
completion_data = io->base.completion_data;
g_object_ref (msg);
- soup_message_set_io_data (msg, NULL);
+ soup_message_clear_io_data (msg);
if (completion_cb)
completion_cb (G_OBJECT (msg), SOUP_MESSAGE_IO_STOLEN, completion_data);
g_object_unref (msg);
}
-static gint
-processing_stage_cmp (gconstpointer a,
- gconstpointer b)
-{
- SoupProcessingStage stage_a = soup_content_processor_get_processing_stage (SOUP_CONTENT_PROCESSOR
((gpointer)a));
- SoupProcessingStage stage_b = soup_content_processor_get_processing_stage (SOUP_CONTENT_PROCESSOR
((gpointer)b));
-
- if (stage_a > stage_b)
- return 1;
- if (stage_a == stage_b)
- return 0;
- return -1;
-}
-
-GInputStream *
-soup_message_setup_body_istream (GInputStream *body_stream,
- SoupMessage *msg,
- SoupSession *session,
- SoupProcessingStage start_at_stage)
-{
- GInputStream *istream;
- GSList *p, *processors;
-
- istream = g_object_ref (body_stream);
-
- processors = soup_session_get_features (session, SOUP_TYPE_CONTENT_PROCESSOR);
- processors = g_slist_sort (processors, processing_stage_cmp);
-
- for (p = processors; p; p = p->next) {
- GInputStream *wrapper;
- SoupContentProcessor *processor;
-
- processor = SOUP_CONTENT_PROCESSOR (p->data);
- if (soup_message_disables_feature (msg, p->data) ||
- soup_content_processor_get_processing_stage (processor) < start_at_stage)
- continue;
-
- wrapper = soup_content_processor_wrap_input (processor, istream, msg, NULL);
- if (wrapper) {
- g_object_unref (istream);
- istream = wrapper;
- }
- }
-
- g_slist_free (processors);
-
- return istream;
-}
-
static void
request_body_stream_wrote_data_cb (SoupMessage *msg,
const void *buffer,
guint count,
gboolean is_metadata)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *client_io = get_io_data (msg);
if (client_io->metrics) {
client_io->metrics->request_body_bytes_sent += count;
@@ -187,14 +152,14 @@ request_body_stream_wrote_cb (GOutputStream *ostream,
GAsyncResult *result,
SoupMessage *msg)
{
- SoupClientMessageIOData *io;
+ SoupMessageIOHTTP1 *io;
gssize nwrote;
GCancellable *async_wait;
GError *error = NULL;
nwrote = g_output_stream_splice_finish (ostream, result, &error);
- io = soup_message_get_io_data (msg);
+ io = get_io_data (msg);
if (!io || !io->base.async_wait || io->base.body_ostream != ostream) {
g_clear_error (&error);
g_object_unref (msg);
@@ -221,10 +186,10 @@ closed_async (GObject *source,
{
GOutputStream *body_ostream = G_OUTPUT_STREAM (source);
SoupMessage *msg = user_data;
- SoupClientMessageIOData *io;
+ SoupMessageIOHTTP1 *io;
GCancellable *async_wait;
- io = soup_message_get_io_data (msg);
+ io = get_io_data (msg);
if (!io || !io->base.async_wait || io->base.body_ostream != body_ostream) {
g_object_unref (msg);
return;
@@ -328,9 +293,9 @@ static gboolean
io_write (SoupMessage *msg, gboolean blocking,
GCancellable *cancellable, GError **error)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *client_io = get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
- SoupSessionFeature *logger;
+ SoupSessionFeature *logger;
gssize nwrote;
if (io->async_error) {
@@ -386,7 +351,8 @@ io_write (SoupMessage *msg, gboolean blocking,
logger = soup_session_get_feature_for_message (client_io->item->session,
SOUP_TYPE_LOGGER, msg);
if (logger)
- soup_logger_request_body_setup (SOUP_LOGGER (logger), msg);
+ soup_logger_request_body_setup (SOUP_LOGGER (logger), msg,
+ SOUP_BODY_OUTPUT_STREAM (io->body_ostream));
break;
case SOUP_MESSAGE_IO_STATE_BODY:
@@ -516,7 +482,7 @@ static void
response_network_stream_read_data_cb (SoupMessage *msg,
guint count)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *client_io = get_io_data (msg);
if (client_io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY_START)
client_io->metrics->response_header_bytes_received += count;
@@ -534,7 +500,7 @@ static gboolean
io_read (SoupMessage *msg, gboolean blocking,
GCancellable *cancellable, GError **error)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *client_io = get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
gboolean succeeded;
gboolean is_first_read;
@@ -605,7 +571,7 @@ io_read (SoupMessage *msg, gboolean blocking,
/* If this was "101 Switching Protocols", then
* the session may have stolen the connection...
*/
- if (client_io != soup_message_get_io_data (msg))
+ if (client_io != get_io_data (msg))
return FALSE;
soup_message_cleanup_response (msg);
@@ -707,7 +673,7 @@ io_read (SoupMessage *msg, gboolean blocking,
static gboolean
request_is_restartable (SoupMessage *msg, GError *error)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *client_io = get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
if (!client_io)
@@ -728,7 +694,7 @@ io_run_until (SoupMessage *msg, gboolean blocking,
SoupMessageIOState read_state, SoupMessageIOState write_state,
GCancellable *cancellable, GError **error)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *client_io = get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
gboolean progress = TRUE, done;
GError *my_error = NULL;
@@ -744,7 +710,7 @@ io_run_until (SoupMessage *msg, gboolean blocking,
g_object_ref (msg);
- while (progress && soup_message_get_io_data (msg) == client_io && !io->paused && !io->async_wait &&
+ while (progress && get_io_data (msg) == client_io && !io->paused && !io->async_wait &&
(io->read_state < read_state || io->write_state < write_state)) {
if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state))
@@ -759,7 +725,7 @@ io_run_until (SoupMessage *msg, gboolean blocking,
g_propagate_error (error, my_error);
g_object_unref (msg);
return FALSE;
- } else if (soup_message_get_io_data (msg) != client_io) {
+ } else if (get_io_data (msg) != client_io) {
g_set_error_literal (error, G_IO_ERROR,
G_IO_ERROR_CANCELLED,
_("Operation was cancelled"));
@@ -814,11 +780,11 @@ io_run_until (SoupMessage *msg, gboolean blocking,
}
static void
-soup_message_io_finish (SoupMessage *msg,
+soup_message_io_http1_finish (SoupMessage *msg,
GError *error)
{
if (request_is_restartable (msg, error)) {
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
/* Connection got closed, but we can safely try again. */
io->item->state = SOUP_MESSAGE_RESTARTING;
@@ -826,21 +792,25 @@ soup_message_io_finish (SoupMessage *msg,
soup_message_set_metrics_timestamp (msg, SOUP_MESSAGE_METRICS_RESPONSE_END);
}
- soup_message_io_finished (msg);
+ soup_message_io_http1_finished (msg);
}
+static void
+soup_message_io_http1_run (SoupMessage *msg,
+ gboolean blocking);
+
static gboolean
io_run_ready (SoupMessage *msg, gpointer user_data)
{
- soup_message_io_run (msg, FALSE);
+ soup_message_io_http1_run (msg, FALSE);
return FALSE;
}
-void
-soup_message_io_run (SoupMessage *msg,
- gboolean blocking)
+static void
+soup_message_io_http1_run (SoupMessage *msg,
+ gboolean blocking)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *client_io = get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
GError *error = NULL;
@@ -856,7 +826,7 @@ soup_message_io_run (SoupMessage *msg,
SOUP_MESSAGE_IO_STATE_DONE,
SOUP_MESSAGE_IO_STATE_DONE,
client_io->item->cancellable, &error)) {
- soup_message_io_finished (msg);
+ soup_message_io_http1_finished (msg);
} else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
g_clear_error (&error);
io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg),
@@ -867,8 +837,8 @@ soup_message_io_run (SoupMessage *msg,
soup_client_message_io_data_get_priority (client_io));
g_source_attach (io->io_source, g_main_context_get_thread_default ());
} else {
- if (soup_message_get_io_data (msg) == client_io)
- soup_message_io_finish (msg, error);
+ if (get_io_data (msg) == client_io)
+ soup_message_io_http1_finish (msg, error);
g_error_free (error);
}
@@ -876,12 +846,12 @@ soup_message_io_run (SoupMessage *msg,
g_object_unref (msg);
}
-gboolean
-soup_message_io_run_until_read (SoupMessage *msg,
+static gboolean
+soup_message_io_http1_run_until_read (SoupMessage *msg,
GCancellable *cancellable,
GError **error)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
if (io_run_until (msg, TRUE,
SOUP_MESSAGE_IO_STATE_BODY,
@@ -889,8 +859,8 @@ soup_message_io_run_until_read (SoupMessage *msg,
cancellable, error))
return TRUE;
- if (soup_message_get_io_data (msg) == io)
- soup_message_io_finish (msg, *error);
+ if (get_io_data (msg) == io)
+ soup_message_io_http1_finish (msg, *error);
return FALSE;
}
@@ -912,7 +882,7 @@ static void
io_run_until_read_async (SoupMessage *msg,
GTask *task)
{
- SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *client_io = get_io_data (msg);
SoupMessageIOData *io = &client_io->base;
GError *error = NULL;
@@ -942,15 +912,15 @@ io_run_until_read_async (SoupMessage *msg,
return;
}
- if (soup_message_get_io_data (msg) == client_io)
- soup_message_io_finish (msg, error);
+ if (get_io_data (msg) == client_io)
+ soup_message_io_http1_finish (msg, error);
g_task_return_error (task, error);
g_object_unref (task);
}
-void
-soup_message_io_run_until_read_async (SoupMessage *msg,
+static void
+soup_message_io_http1_run_until_read_async (SoupMessage *msg,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -963,21 +933,13 @@ soup_message_io_run_until_read_async (SoupMessage *msg,
io_run_until_read_async (msg, task);
}
-gboolean
-soup_message_io_run_until_read_finish (SoupMessage *msg,
- GAsyncResult *result,
- GError **error)
-{
- return g_task_propagate_boolean (G_TASK (result), error);
-}
-
-gboolean
-soup_message_io_run_until_finish (SoupMessage *msg,
+static gboolean
+soup_message_io_http1_run_until_finish (SoupMessage *msg,
gboolean blocking,
GCancellable *cancellable,
GError **error)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
gboolean success;
g_object_ref (msg);
@@ -1000,17 +962,17 @@ static void
client_stream_eof (SoupClientInputStream *stream, gpointer user_data)
{
SoupMessage *msg = user_data;
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
if (io && io->base.read_state == SOUP_MESSAGE_IO_STATE_BODY)
io->base.read_state = SOUP_MESSAGE_IO_STATE_BODY_DONE;
}
-GInputStream *
-soup_message_io_get_response_istream (SoupMessage *msg,
+static GInputStream *
+soup_message_io_http1_get_response_istream (SoupMessage *msg,
GError **error)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
GInputStream *client_stream;
client_stream = soup_client_input_stream_new (io->base.body_istream, msg);
@@ -1020,14 +982,20 @@ soup_message_io_get_response_istream (SoupMessage *msg,
return client_stream;
}
-void
-soup_message_send_request (SoupMessageQueueItem *item,
- SoupMessageIOCompletionFn completion_cb,
- gpointer user_data)
+SoupMessageIOHTTP1 *
+soup_message_io_http1_new (void)
+{
+ return g_object_new (SOUP_TYPE_MESSAGE_IO_HTTP1, NULL);
+}
+
+static void
+soup_message_io_http1_send_item (SoupMessageIOBackend *backend,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data)
{
- SoupClientMessageIOData *io;
+ SoupMessageIOHTTP1 *io = (SoupMessageIOHTTP1 *)backend;
- io = g_slice_new0 (SoupClientMessageIOData);
io->base.completion_cb = completion_cb;
io->base.completion_data = user_data;
@@ -1052,49 +1020,83 @@ soup_message_send_request (SoupMessageQueueItem *item,
#ifdef HAVE_SYSPROF
io->begin_time_nsec = SYSPROF_CAPTURE_CURRENT_TIME;
#endif
-
- soup_message_set_io_data (io->item->msg, io);
}
-void
-soup_message_io_pause (SoupMessage *msg)
+
+static void
+soup_message_io_http1_pause (SoupMessage *msg)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
- g_return_if_fail (io != NULL);
g_return_if_fail (io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY);
soup_message_io_data_pause (&io->base);
}
-void
-soup_message_io_unpause (SoupMessage *msg)
+static void
+soup_message_io_http1_unpause (SoupMessage *msg)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
- g_return_if_fail (io != NULL);
g_return_if_fail (io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY);
io->base.paused = FALSE;
}
-/**
- * soup_message_io_in_progress:
- * @msg: a #SoupMessage
- *
- * Tests whether or not I/O is currently in progress on @msg.
- *
- * Returns: whether or not I/O is currently in progress.
- **/
-gboolean
-soup_message_io_in_progress (SoupMessage *msg)
+static gboolean
+soup_message_io_http1_in_progress (SoupMessage *msg)
+{
+ return TRUE; // True as long as this object is alive
+}
+
+static gboolean
+soup_message_io_http1_is_paused (SoupMessage *msg)
+{
+ SoupMessageIOHTTP1 *io = get_io_data (msg);
+
+ return io->base.paused;
+}
+
+static void
+soup_message_io_http1_finalize (GObject *object)
+{
+ SoupMessageIOHTTP1 *io = (SoupMessageIOHTTP1 *)object;
+
+ if (io->item) {
+ soup_message_set_io_data (io->item->msg, NULL);
+ g_clear_pointer (&io->item, soup_message_queue_item_unref);
+ }
+
+ soup_message_io_data_cleanup (&io->base);
+
+ G_OBJECT_CLASS (soup_message_io_http1_parent_class)->finalize (object);
+}
+
+static void
+soup_message_io_http1_init (SoupMessageIOHTTP1 *self)
{
- return soup_message_get_io_data (msg) != NULL;
}
-gboolean
-soup_message_is_io_paused (SoupMessage *msg)
+static void
+soup_message_io_http1_class_init (SoupMessageIOHTTP1Class *klass)
{
- SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- return io && io->base.paused;
+ gobject_class->finalize = soup_message_io_http1_finalize;
}
+
+static void
+soup_message_io_http1_iface_init (SoupMessageIOBackendInterface *iface)
+{
+ iface->finished = soup_message_io_http1_finished;
+ iface->stolen = soup_message_io_http1_stolen;
+ iface->pause = soup_message_io_http1_pause;
+ iface->unpause = soup_message_io_http1_unpause;
+ iface->is_paused = soup_message_io_http1_is_paused;
+ iface->in_progress = soup_message_io_http1_in_progress;
+ iface->get_response_istream = soup_message_io_http1_get_response_istream;
+ iface->run = soup_message_io_http1_run;
+ iface->run_until_read = soup_message_io_http1_run_until_read;
+ iface->run_until_finish = soup_message_io_http1_run_until_finish;
+ iface->run_until_read_async = soup_message_io_http1_run_until_read_async;
+ iface->send_item = soup_message_io_http1_send_item;
+}
\ No newline at end of file
diff --git a/libsoup/soup-message-io-http1.h b/libsoup/soup-message-io-http1.h
new file mode 100644
index 00000000..e044b92a
--- /dev/null
+++ b/libsoup/soup-message-io-http1.h
@@ -0,0 +1,33 @@
+/* soup-message-io-http1.h
+ *
+ * Copyright 2020 Igalia S.L.
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ */
+
+#pragma once
+
+#include "soup-message-io-backend.h"
+#include "soup-message-io-data.h"
+
+G_BEGIN_DECLS
+
+#define SOUP_TYPE_MESSAGE_IO_HTTP1 (soup_message_io_http1_get_type())
+G_DECLARE_FINAL_TYPE (SoupMessageIOHTTP1, soup_message_io_http1, SOUP, MESSAGE_IO_HTTP1, GObject)
+
+SoupMessageIOHTTP1 *soup_message_io_http1_new (void);
+
+G_END_DECLS
\ No newline at end of file
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index 05e0dcc9..11684ad8 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -8,6 +8,7 @@
#include "soup-filter-input-stream.h"
#include "soup-message.h"
+#include "soup-message-io-backend.h"
#include "soup-message-io-data.h"
#include "auth/soup-auth.h"
#include "soup-content-processor.h"
@@ -33,10 +34,6 @@ typedef guint (*SoupMessageParseHeadersFn)(SoupMessage *msg,
gpointer user_data,
GError **error);
-void soup_message_send_request (SoupMessageQueueItem *item,
- SoupMessageIOCompletionFn completion_cb,
- gpointer user_data);
-
/* Auth handling */
void soup_message_set_auth (SoupMessage *msg,
SoupAuth *auth);
@@ -46,50 +43,6 @@ void soup_message_set_proxy_auth (SoupMessage *msg,
SoupAuth *soup_message_get_proxy_auth (SoupMessage *msg);
GUri *soup_message_get_uri_for_auth (SoupMessage *msg);
-/* I/O */
-void soup_message_io_run (SoupMessage *msg,
- gboolean blocking);
-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_is_io_paused (SoupMessage *msg);
-gboolean soup_message_io_in_progress (SoupMessage *msg);
-void soup_message_io_stolen (SoupMessage *msg);
-
-gboolean soup_message_io_read_headers (SoupMessage *msg,
- SoupFilterInputStream *stream,
- GByteArray *buffer,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error);
-
-gboolean soup_message_io_run_until_finish (SoupMessage *msg,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error);
-
-gboolean soup_message_io_run_until_read (SoupMessage *msg,
- GCancellable *cancellable,
- GError **error);
-void soup_message_io_run_until_read_async (SoupMessage *msg,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean soup_message_io_run_until_read_finish (SoupMessage *msg,
- GAsyncResult *result,
- GError **error);
-
-typedef gboolean (*SoupMessageSourceFunc) (SoupMessage *, gpointer);
-GSource *soup_message_io_get_source (SoupMessage *msg,
- GCancellable *cancellable,
- SoupMessageSourceFunc callback,
- gpointer user_data);
-
-GInputStream *soup_message_io_get_response_istream (SoupMessage *msg,
- GError **error);
-
void soup_message_wrote_headers (SoupMessage *msg);
void soup_message_wrote_body_data (SoupMessage *msg,
gsize chunk_size);
@@ -122,9 +75,10 @@ SoupConnection *soup_message_get_connection (SoupMessage *msg);
void soup_message_set_connection (SoupMessage *msg,
SoupConnection *conn);
-SoupClientMessageIOData *soup_message_get_io_data (SoupMessage *msg);
+SoupMessageIOBackend *soup_message_get_io_data (SoupMessage *msg);
void soup_message_set_io_data (SoupMessage *msg,
- SoupClientMessageIOData *io);
+ SoupMessageIOBackend *io);
+void soup_message_clear_io_data (SoupMessage *msg);
SoupContentSniffer *soup_message_get_content_sniffer (SoupMessage *msg);
void soup_message_set_content_sniffer (SoupMessage *msg,
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 87adc6f4..748ce320 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -59,7 +59,7 @@ struct _SoupMessage {
};
typedef struct {
- SoupClientMessageIOData *io_data;
+ SoupMessageIOBackend *io_data;
SoupMessageHeaders *request_headers;
SoupMessageHeaders *response_headers;
@@ -166,7 +166,7 @@ soup_message_finalize (GObject *object)
soup_message_set_connection (msg, NULL);
- soup_client_message_io_data_free (priv->io_data);
+ g_clear_object (&priv->io_data);
g_clear_pointer (&priv->uri, g_uri_unref);
g_clear_pointer (&priv->first_party, g_uri_unref);
@@ -2136,7 +2136,7 @@ soup_message_get_priority (SoupMessage *msg)
return priv->priority;
}
-SoupClientMessageIOData *
+SoupMessageIOBackend *
soup_message_get_io_data (SoupMessage *msg)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
@@ -2144,13 +2144,22 @@ soup_message_get_io_data (SoupMessage *msg)
return priv->io_data;
}
+void
+soup_message_clear_io_data (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ g_clear_object (&priv->io_data);
+}
+
void
soup_message_set_io_data (SoupMessage *msg,
- SoupClientMessageIOData *io)
+ SoupMessageIOBackend *io)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
- soup_client_message_io_data_free (priv->io_data);
+ g_assert (!priv->io_data);
+
priv->io_data = io;
}
@@ -2181,6 +2190,55 @@ soup_message_set_bytes_for_sniffing (SoupMessage *msg, gsize bytes)
priv->bytes_for_sniffing = bytes;
}
+static gint
+processing_stage_cmp (gconstpointer a,
+ gconstpointer b)
+{
+ SoupProcessingStage stage_a = soup_content_processor_get_processing_stage (SOUP_CONTENT_PROCESSOR
((gpointer)a));
+ SoupProcessingStage stage_b = soup_content_processor_get_processing_stage (SOUP_CONTENT_PROCESSOR
((gpointer)b));
+
+ if (stage_a > stage_b)
+ return 1;
+ if (stage_a == stage_b)
+ return 0;
+ return -1;
+}
+
+GInputStream *
+soup_message_setup_body_istream (GInputStream *body_stream,
+ SoupMessage *msg,
+ SoupSession *session,
+ SoupProcessingStage start_at_stage)
+{
+ GInputStream *istream;
+ GSList *p, *processors;
+
+ istream = g_object_ref (body_stream);
+
+ processors = soup_session_get_features (session, SOUP_TYPE_CONTENT_PROCESSOR);
+ processors = g_slist_sort (processors, processing_stage_cmp);
+
+ for (p = processors; p; p = p->next) {
+ GInputStream *wrapper;
+ SoupContentProcessor *processor;
+
+ processor = SOUP_CONTENT_PROCESSOR (p->data);
+ if (soup_message_disables_feature (msg, p->data) ||
+ soup_content_processor_get_processing_stage (processor) < start_at_stage)
+ continue;
+
+ wrapper = soup_content_processor_wrap_input (processor, istream, msg, NULL);
+ if (wrapper) {
+ g_object_unref (istream);
+ istream = wrapper;
+ }
+ }
+
+ g_slist_free (processors);
+
+ return istream;
+}
+
GInputStream *
soup_message_get_request_body_stream (SoupMessage *msg)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]