[evolution-data-server] Enhance ESoupSession debug logging
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Enhance ESoupSession debug logging
- Date: Thu, 2 Jul 2020 11:40:56 +0000 (UTC)
commit 3764631f47159a1546abca14b9701220de67d070
Author: Milan Crha <mcrha redhat com>
Date: Thu Jul 2 13:37:46 2020 +0200
Enhance ESoupSession debug logging
It required specific code to have logged GInputStream data from a SoupRequest.
It could be made transparent to the caller, thus avoid this special code.
.../evolution-data-server-docs.sgml.in | 1 +
src/calendar/backends/http/e-cal-backend-http.c | 16 --
src/libedataserver/CMakeLists.txt | 2 +
src/libedataserver/e-soup-logger.c | 201 +++++++++++++++++++++
src/libedataserver/e-soup-logger.h | 32 ++++
src/libedataserver/e-soup-session.c | 10 +-
src/libedataserver/e-webdav-session.c | 21 ---
src/libedataserver/libedataserver.h | 1 +
8 files changed, 241 insertions(+), 43 deletions(-)
---
diff --git a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
index f1918ed9b..a3fb65e82 100644
--- a/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
+++ b/docs/reference/evolution-data-server/evolution-data-server-docs.sgml.in
@@ -248,6 +248,7 @@
<xi:include href="xml/e-operation-pool.xml"/>
<xi:include href="xml/e-secret-store.xml"/>
<xi:include href="xml/e-sexp.xml"/>
+ <xi:include href="xml/e-soup-logger.xml"/>
<xi:include href="xml/e-soup-session.xml"/>
<xi:include href="xml/e-soup-ssl-trust.xml"/>
<xi:include href="xml/e-source-registry-watcher.xml"/>
diff --git a/src/calendar/backends/http/e-cal-backend-http.c b/src/calendar/backends/http/e-cal-backend-http.c
index 5f633a8ed..96ca1f340 100644
--- a/src/calendar/backends/http/e-cal-backend-http.c
+++ b/src/calendar/backends/http/e-cal-backend-http.c
@@ -256,17 +256,6 @@ ecb_http_connect_sync (ECalMetaBackend *meta_backend,
success = input_stream != NULL;
if (success && message && !SOUP_STATUS_IS_SUCCESSFUL (message->status_code) &&
message->status_code != SOUP_STATUS_NOT_MODIFIED) {
- if (input_stream && e_soup_session_get_log_level (cbhttp->priv->session) ==
SOUP_LOGGER_LOG_BODY) {
- gchar *response = ecb_http_read_stream_sync (input_stream, -1, cancellable,
NULL);
-
- if (response) {
- printf ("%s\n", response);
- fflush (stdout);
-
- g_free (response);
- }
- }
-
g_clear_object (&input_stream);
success = FALSE;
}
@@ -460,11 +449,6 @@ ecb_http_get_changes_sync (ECalMetaBackend *meta_backend,
return FALSE;
}
- if (e_soup_session_get_log_level (cbhttp->priv->session) == SOUP_LOGGER_LOG_BODY) {
- printf ("%s\n", icalstring);
- fflush (stdout);
- }
-
/* Skip the UTF-8 marker at the beginning of the string */
if (((guchar) icalstring[0]) == 0xEF &&
((guchar) icalstring[1]) == 0xBB &&
diff --git a/src/libedataserver/CMakeLists.txt b/src/libedataserver/CMakeLists.txt
index 17be15469..fa86153d9 100644
--- a/src/libedataserver/CMakeLists.txt
+++ b/src/libedataserver/CMakeLists.txt
@@ -74,6 +74,7 @@ set(SOURCES
e-secret-store.c
e-sexp.c
e-soup-auth-bearer.c
+ e-soup-logger.c
e-soup-session.c
e-soup-ssl-trust.c
e-source.c
@@ -163,6 +164,7 @@ set(HEADERS
e-secret-store.h
e-sexp.h
e-soup-auth-bearer.h
+ e-soup-logger.h
e-soup-session.h
e-soup-ssl-trust.h
e-source.h
diff --git a/src/libedataserver/e-soup-logger.c b/src/libedataserver/e-soup-logger.c
new file mode 100644
index 000000000..bcb099821
--- /dev/null
+++ b/src/libedataserver/e-soup-logger.c
@@ -0,0 +1,201 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat (www.redhat.com)
+ *
+ * This library 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.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "evolution-data-server-config.h"
+
+#include <stdio.h>
+#include <libsoup/soup.h>
+
+#include "e-soup-logger.h"
+
+/* Standard GObject macros */
+#define E_TYPE_SOUP_LOGGER \
+ (e_soup_logger_get_type ())
+#define E_SOUP_LOGGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SOUP_LOGGER, EO365SoupLogger))
+#define E_SOUP_LOGGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SOUP_LOGGER, EO365SoupLoggerClass))
+#define E_IS_SOUP_LOGGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SOUP_LOGGER))
+#define E_IS_SOUP_LOGGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SOUP_LOGGER))
+#define E_SOUP_LOGGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SOUP_LOGGER))
+
+G_BEGIN_DECLS
+
+typedef struct _EO365SoupLogger EO365SoupLogger;
+typedef struct _EO365SoupLoggerClass EO365SoupLoggerClass;
+
+struct _EO365SoupLogger {
+ GObject parent;
+
+ GByteArray *data;
+};
+
+struct _EO365SoupLoggerClass {
+ GObjectClass parent_class;
+};
+
+GType e_soup_logger_get_type (void) G_GNUC_CONST;
+
+static void e_soup_logger_converter_interface_init
+ (GConverterIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (EO365SoupLogger, e_soup_logger, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, e_soup_logger_converter_interface_init))
+
+static GConverterResult
+e_soup_logger_convert (GConverter *converter,
+ gconstpointer inbuf,
+ gsize inbuf_size,
+ gpointer outbuf,
+ gsize outbuf_size,
+ GConverterFlags flags,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ EO365SoupLogger *logger = E_SOUP_LOGGER (converter);
+ GConverterResult result;
+ gsize min_size;
+
+ min_size = MIN (inbuf_size, outbuf_size);
+
+ if (inbuf && min_size)
+ memcpy (outbuf, inbuf, min_size);
+ *bytes_read = *bytes_written = min_size;
+
+ if (!logger->data)
+ logger->data = g_byte_array_sized_new (10240);
+
+ g_byte_array_append (logger->data, (const guint8 *) outbuf, (guint) min_size);
+
+ if ((flags & G_CONVERTER_INPUT_AT_END) != 0)
+ result = G_CONVERTER_FINISHED;
+ else if ((flags & G_CONVERTER_FLUSH) != 0)
+ result = G_CONVERTER_FLUSHED;
+ else
+ result = G_CONVERTER_CONVERTED;
+
+ return result;
+}
+
+static void
+e_soup_logger_reset (GConverter *converter)
+{
+ /* Nothing to do. */
+}
+
+static void
+e_soup_logger_print_data (EO365SoupLogger *logger)
+{
+ if (logger->data) {
+ fwrite (logger->data->data, 1, logger->data->len, stdout);
+ fwrite ("\n\n", 1, 2, stdout);
+
+ g_byte_array_free (logger->data, TRUE);
+ logger->data = NULL;
+ }
+
+ fflush (stdout);
+}
+
+static void
+e_soup_logger_message_finished_cb (SoupMessage *msg,
+ gpointer user_data)
+{
+ EO365SoupLogger *logger = user_data;
+
+ g_return_if_fail (E_IS_SOUP_LOGGER (logger));
+
+ e_soup_logger_print_data (logger);
+}
+
+static void
+o365_soup_logger_finalize (GObject *object)
+{
+ EO365SoupLogger *logger = E_SOUP_LOGGER (object);
+
+ e_soup_logger_print_data (logger);
+
+ /* Chain up to parent's method. */
+ G_OBJECT_CLASS (e_soup_logger_parent_class)->finalize (object);
+}
+
+static void
+e_soup_logger_class_init (EO365SoupLoggerClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = o365_soup_logger_finalize;
+}
+
+static void
+e_soup_logger_converter_interface_init (GConverterIface *iface)
+{
+ iface->convert = e_soup_logger_convert;
+ iface->reset = e_soup_logger_reset;
+}
+
+static void
+e_soup_logger_init (EO365SoupLogger *logger)
+{
+}
+
+/**
+ * e_soup_logger_attach:
+ * @message: a #SoupMessage
+ * @input_stream: (transfer full): a #GInputStream, associated with the @message
+ *
+ * Remembers what had been read from the @input_stream and prints it
+ * to stdout when the @message is finished. The function assumes
+ * ownership of the @input_stream.
+ *
+ * Returns: (transfer full): a new input stream, to be used instead of the @input_stream.
+ * It should be freed with g_object_unref(), when no longer needed.
+ *
+ * Since: 3.38
+ **/
+GInputStream *
+e_soup_logger_attach (SoupMessage *message,
+ GInputStream *input_stream)
+{
+ GConverter *logger;
+ GInputStream *filter_stream;
+
+ g_return_val_if_fail (SOUP_IS_MESSAGE (message), input_stream);
+ g_return_val_if_fail (G_IS_INPUT_STREAM (input_stream), input_stream);
+
+ logger = g_object_new (E_TYPE_SOUP_LOGGER, NULL);
+
+ filter_stream = g_converter_input_stream_new (input_stream, logger);
+ g_object_set_data_full (G_OBJECT (message), "ESoupLogger", logger, g_object_unref);
+
+ g_signal_connect_object (message, "finished",
+ G_CALLBACK (e_soup_logger_message_finished_cb), logger, G_CONNECT_AFTER);
+
+ g_object_unref (input_stream);
+
+ return filter_stream;
+}
diff --git a/src/libedataserver/e-soup-logger.h b/src/libedataserver/e-soup-logger.h
new file mode 100644
index 000000000..06a1758b1
--- /dev/null
+++ b/src/libedataserver/e-soup-logger.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2020 Red Hat (www.redhat.com)
+ *
+ * This library 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.
+ *
+ * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (__LIBEDATASERVER_H_INSIDE__) && !defined (LIBEDATASERVER_COMPILATION)
+#error "Only <libedataserver/libedateserver.h> should be included directly."
+#endif
+
+#ifndef E_SOUP_LOGGER_H
+#define E_SOUP_LOGGER_H
+
+#include <libsoup/soup.h>
+
+GInputStream * e_soup_logger_attach (SoupMessage *message,
+ GInputStream *input_stream);
+
+G_END_DECLS
+
+#endif /* E_SOUP_LOGGER_H */
diff --git a/src/libedataserver/e-soup-session.c b/src/libedataserver/e-soup-session.c
index a06bfb15e..9ce03bee3 100644
--- a/src/libedataserver/e-soup-session.c
+++ b/src/libedataserver/e-soup-session.c
@@ -31,6 +31,7 @@
#include "e-oauth2-services.h"
#include "e-soup-auth-bearer.h"
+#include "e-soup-logger.h"
#include "e-soup-ssl-trust.h"
#include "e-source-authentication.h"
#include "e-source-webdav.h"
@@ -1065,6 +1066,9 @@ e_soup_session_send_request_sync (ESoupSession *session,
if (input_stream) {
message = soup_request_http_get_message (request);
+ if (message && e_soup_session_get_log_level (session) == SOUP_LOGGER_LOG_BODY)
+ input_stream = e_soup_logger_attach (message, input_stream);
+
if (message && SOUP_STATUS_IS_REDIRECTION (message->status_code)) {
/* libsoup uses 20, but the constant is not in any public header */
if (resend_count >= 30) {
@@ -1180,12 +1184,6 @@ e_soup_session_send_request_simple_sync (ESoupSession *session,
g_free (buffer);
g_object_unref (input_stream);
- if (bytes->len > 0 && e_soup_session_get_log_level (session) == SOUP_LOGGER_LOG_BODY) {
- fwrite (bytes->data, 1, bytes->len, stdout);
- fprintf (stdout, "\n");
- fflush (stdout);
- }
-
if (success)
success = e_soup_session_check_result (session, request, bytes->data, bytes->len, error);
diff --git a/src/libedataserver/e-webdav-session.c b/src/libedataserver/e-webdav-session.c
index f254a84fb..1af7c2a3c 100644
--- a/src/libedataserver/e-webdav-session.c
+++ b/src/libedataserver/e-webdav-session.c
@@ -2100,7 +2100,6 @@ e_webdav_session_get_sync (EWebDAVSession *webdav,
success = input_stream != NULL;
if (success) {
- SoupLoggerLogLevel log_level = e_soup_session_get_log_level (E_SOUP_SESSION (webdav));
gpointer buffer;
gsize nread = 0, nwritten;
gboolean first_chunk = TRUE;
@@ -2109,11 +2108,6 @@ e_webdav_session_get_sync (EWebDAVSession *webdav,
while (success = g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &nread,
cancellable, error),
success && nread > 0) {
- if (log_level == SOUP_LOGGER_LOG_BODY) {
- fwrite (buffer, 1, nread, stdout);
- fflush (stdout);
- }
-
if (first_chunk) {
GByteArray tmp_bytes;
@@ -2134,9 +2128,6 @@ e_webdav_session_get_sync (EWebDAVSession *webdav,
if (success && first_chunk) {
success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request,
NULL, FALSE, _("Failed to read resource"), error, TRUE, TRUE);
- } else if (success && !first_chunk && log_level == SOUP_LOGGER_LOG_BODY) {
- fprintf (stdout, "\n");
- fflush (stdout);
}
g_free (buffer);
@@ -2222,7 +2213,6 @@ e_webdav_session_get_data_sync (EWebDAVSession *webdav,
typedef struct _ChunkWriteData {
SoupSession *session;
- SoupLoggerLogLevel log_level;
GInputStream *stream;
goffset read_from;
gboolean wrote_any;
@@ -2252,11 +2242,6 @@ e_webdav_session_write_next_chunk (SoupMessage *message,
} else {
cwd->wrote_any = TRUE;
soup_message_body_append (message->request_body, SOUP_MEMORY_TEMPORARY, cwd->buffer, nread);
-
- if (cwd->log_level == SOUP_LOGGER_LOG_BODY) {
- fwrite (cwd->buffer, 1, nread, stdout);
- fflush (stdout);
- }
}
}
@@ -2418,7 +2403,6 @@ e_webdav_session_put_sync (EWebDAVSession *webdav,
}
cwd.session = SOUP_SESSION (webdav);
- cwd.log_level = e_soup_session_get_log_level (E_SOUP_SESSION (webdav));
cwd.stream = stream;
cwd.read_from = 0;
cwd.wrote_any = FALSE;
@@ -2450,11 +2434,6 @@ e_webdav_session_put_sync (EWebDAVSession *webdav,
success = !e_webdav_session_replace_with_detailed_error_internal (webdav, request, bytes, FALSE,
_("Failed to put data"), error, TRUE, TRUE) &&
bytes != NULL;
- if (cwd.wrote_any && cwd.log_level == SOUP_LOGGER_LOG_BODY) {
- fprintf (stdout, "\n");
- fflush (stdout);
- }
-
if (cwd.error) {
g_clear_error (error);
g_propagate_error (error, cwd.error);
diff --git a/src/libedataserver/libedataserver.h b/src/libedataserver/libedataserver.h
index 6f872098a..cee5b6054 100644
--- a/src/libedataserver/libedataserver.h
+++ b/src/libedataserver/libedataserver.h
@@ -48,6 +48,7 @@
#include <libedataserver/e-secret-store.h>
#include <libedataserver/e-sexp.h>
#include <libedataserver/e-soup-auth-bearer.h>
+#include <libedataserver/e-soup-logger.h>
#include <libedataserver/e-soup-session.h>
#include <libedataserver/e-soup-ssl-trust.h>
#include <libedataserver/e-source-address-book.h>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]