[evolution-data-server] I#404 - ESoupSession: Remember server fail response for detailed error
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#404 - ESoupSession: Remember server fail response for detailed error
- Date: Thu, 7 Jul 2022 17:28:17 +0000 (UTC)
commit b20dbad4b125a703b125ef73772063e0d0e7452a
Author: Milan Crha <mcrha redhat com>
Date: Thu Jul 7 19:27:47 2022 +0200
I#404 - ESoupSession: Remember server fail response for detailed error
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/404
src/libedataserver/e-soup-session.c | 125 ++++++++++++++++++++++++++++------
src/libedataserver/e-soup-session.h | 1 +
src/libedataserver/e-webdav-session.c | 7 ++
3 files changed, 112 insertions(+), 21 deletions(-)
---
diff --git a/src/libedataserver/e-soup-session.c b/src/libedataserver/e-soup-session.c
index a004e2106..cb7a3bf05 100644
--- a/src/libedataserver/e-soup-session.c
+++ b/src/libedataserver/e-soup-session.c
@@ -40,6 +40,7 @@
G_DEFINE_QUARK (e-soup-session-error-quark, e_soup_session_error)
+#define E_SOUP_SESSION_MESSAGE_BYTES_KEY "e-soup-session-message-bytes"
#define BUFFER_SIZE 16384
struct _ESoupSessionPrivate {
@@ -1240,6 +1241,56 @@ e_soup_session_prepare_message_send_sync (ESoupSession *session,
return NULL;
}
+static GByteArray *
+e_soup_session_read_bytes (SoupMessage *message,
+ GInputStream *input_stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GByteArray *bytes;
+ goffset expected_length;
+ gpointer buffer;
+ gsize nread = 0;
+ gboolean success = FALSE;
+
+ expected_length = soup_message_headers_get_content_length (soup_message_get_response_headers
(message));
+ if (expected_length > 0)
+ bytes = g_byte_array_sized_new (expected_length > 1024 * 1024 * 10 ? 1024 * 1024 * 10 :
expected_length);
+ else
+ bytes = g_byte_array_new ();
+
+ buffer = g_malloc (BUFFER_SIZE);
+
+ while (success = g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &nread, cancellable,
error),
+ success && nread > 0) {
+ g_byte_array_append (bytes, buffer, nread);
+ }
+
+ g_free (buffer);
+
+ if (!success)
+ g_clear_pointer (&bytes, g_byte_array_unref);
+
+ return bytes;
+}
+
+static void
+e_soup_session_store_data_on_message (SoupMessage *message,
+ GInputStream *input_stream,
+ GCancellable *cancellable)
+{
+ if (input_stream) {
+ GByteArray *bytes;
+
+ bytes = e_soup_session_read_bytes (message, input_stream, cancellable, NULL);
+
+ if (bytes) {
+ g_object_set_data_full (G_OBJECT (message), E_SOUP_SESSION_MESSAGE_BYTES_KEY,
+ bytes, (GDestroyNotify) g_byte_array_unref);
+ }
+ }
+}
+
static void
e_soup_session_send_message_ready_cb (GObject *source_object,
GAsyncResult *result,
@@ -1263,11 +1314,18 @@ e_soup_session_send_message_ready_cb (GObject *source_object,
message = soup_session_get_async_result_message (session, result);
if (message) {
+ if (!SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (message))) {
+ e_soup_session_store_data_on_message (message, input_stream, NULL);
+ g_clear_object (&input_stream);
+ }
+
if (g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE)) {
e_soup_session_extract_ssl_data (E_SOUP_SESSION (session), message,
&asd->certificate_pem, &asd->certificate_errors);
} else if (!local_error && !SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (message))) {
+ GByteArray *bytes = e_soup_session_util_get_message_bytes (message);
+
if (soup_message_get_status (message) != SOUP_STATUS_FORBIDDEN ||
- !e_soup_session_extract_google_daily_limit_error (NULL, 0, &local_error))
+ !e_soup_session_extract_google_daily_limit_error (bytes ? bytes->data : NULL,
bytes ? bytes->len : 0, &local_error))
g_set_error_literal (&local_error, E_SOUP_SESSION_ERROR,
soup_message_get_status (message),
soup_message_get_reason_phrase (message));
}
@@ -1502,11 +1560,18 @@ e_soup_session_send_message_sync (ESoupSession *session,
if (restarted_id)
g_signal_handler_disconnect (message, restarted_id);
+ if (!SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (message))) {
+ e_soup_session_store_data_on_message (message, input_stream, cancellable);
+ g_clear_object (&input_stream);
+ }
+
if (g_error_matches (local_error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE)) {
e_soup_session_extract_ssl_data_internal (session, message);
} else if (!local_error && !SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (message))) {
+ GByteArray *bytes = e_soup_session_util_get_message_bytes (message);
+
if (soup_message_get_status (message) != SOUP_STATUS_FORBIDDEN ||
- !e_soup_session_extract_google_daily_limit_error (NULL, 0, error))
+ !e_soup_session_extract_google_daily_limit_error (bytes ? bytes->data : NULL, bytes ?
bytes->len : 0, error))
g_set_error_literal (&local_error, E_SOUP_SESSION_ERROR, soup_message_get_status
(message),
soup_message_get_reason_phrase (message));
}
@@ -1544,41 +1609,39 @@ e_soup_session_send_message_simple_sync (ESoupSession *session,
{
GInputStream *input_stream;
GByteArray *bytes;
- gint expected_length;
- gpointer buffer;
- gsize nread = 0;
gboolean success = FALSE;
g_return_val_if_fail (E_IS_SOUP_SESSION (session), NULL);
g_return_val_if_fail (SOUP_IS_MESSAGE (message), NULL);
input_stream = e_soup_session_send_message_sync (session, message, cancellable, error);
- if (!input_stream)
- return NULL;
- expected_length = soup_message_headers_get_content_length (soup_message_get_response_headers
(message));
- if (expected_length > 0)
- bytes = g_byte_array_sized_new (expected_length > 1024 * 1024 * 10 ? 1024 * 1024 * 10 :
expected_length);
- else
- bytes = g_byte_array_new ();
+ if (!input_stream) {
+ bytes = e_soup_session_util_get_message_bytes (message);
- buffer = g_malloc (BUFFER_SIZE);
+ if (bytes) {
+ GError *local_error = NULL;
- while (success = g_input_stream_read_all (input_stream, buffer, BUFFER_SIZE, &nread, cancellable,
error),
- success && nread > 0) {
- g_byte_array_append (bytes, buffer, nread);
+ if (!e_soup_session_check_result (session, message, bytes->data, bytes->len,
&local_error) && local_error) {
+ g_clear_error (error);
+ g_propagate_error (error, local_error);
+ }
+ }
+
+ return NULL;
}
- g_free (buffer);
+ bytes = e_soup_session_read_bytes (message, input_stream, cancellable, error);
+
g_object_unref (input_stream);
+ success = bytes != NULL;
+
if (success)
success = e_soup_session_check_result (session, message, bytes->data, bytes->len, error);
- if (!success) {
- g_byte_array_free (bytes, TRUE);
- bytes = NULL;
- }
+ if (!success)
+ g_clear_pointer (&bytes, g_byte_array_unref);
return bytes;
}
@@ -2006,3 +2069,23 @@ e_soup_session_util_ref_message_request_body (SoupMessage *message,
return e_input_stream_wrapper_dup (E_INPUT_STREAM_WRAPPER (md->input_stream));
}
+
+/**
+ * e_soup_session_util_get_message_bytes:
+ * @message: a #SoupMessage
+ *
+ * Returns bytes read from the message response, when the message send failed.
+ * This can be used to examine detailed error returned by the server in
+ * the response body.
+ *
+ * Returns: (transfer none) (nullable): read message data on failed request, or %NULL, when none had been
read
+ *
+ * Since: 3.46
+ **/
+GByteArray *
+e_soup_session_util_get_message_bytes (SoupMessage *message)
+{
+ g_return_val_if_fail (SOUP_IS_MESSAGE (message), NULL);
+
+ return g_object_get_data (G_OBJECT (message), E_SOUP_SESSION_MESSAGE_BYTES_KEY);
+}
diff --git a/src/libedataserver/e-soup-session.h b/src/libedataserver/e-soup-session.h
index d878814e1..28554ccc2 100644
--- a/src/libedataserver/e-soup-session.h
+++ b/src/libedataserver/e-soup-session.h
@@ -132,6 +132,7 @@ GByteArray * e_soup_session_send_message_simple_sync (ESoupSession *session,
SoupMessage *message,
GCancellable *cancellable,
GError **error);
+GByteArray * e_soup_session_util_get_message_bytes (SoupMessage *message);
const gchar * e_soup_session_util_status_to_string (guint status_code,
const gchar *reason_phrase);
GUri * e_soup_session_util_normalize_uri_path (GUri *uri);
diff --git a/src/libedataserver/e-webdav-session.c b/src/libedataserver/e-webdav-session.c
index 41da2483e..303af718e 100644
--- a/src/libedataserver/e-webdav-session.c
+++ b/src/libedataserver/e-webdav-session.c
@@ -891,6 +891,13 @@ e_webdav_session_replace_with_detailed_error_internal (EWebDAVSession *webdav,
if (response_data && response_data->len) {
byte_array.data = (gpointer) response_data->data;
byte_array.len = response_data->len;
+ } else {
+ GByteArray *bytes = e_soup_session_util_get_message_bytes (message);
+
+ if (bytes) {
+ byte_array.data = bytes->data;
+ byte_array.len = bytes->len;
+ }
}
if (!byte_array.data || !byte_array.len)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]