From 42c5b6248a5120026cbdc4f8fe55282fde2df946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Wed, 30 Aug 2023 17:19:39 +0200 Subject: [PATCH] engine: Detect mime encoding constraint from server EHLO Fix #1416 --- src/client/composer/composer-widget.vala | 2 +- .../plugin/mail-merge/mail-merge-folder.vala | 2 +- src/engine/rfc822/rfc822-message.vala | 6 +++++- src/engine/smtp/smtp-capabilities.vala | 1 + src/engine/smtp/smtp-client-service.vala | 20 ++++++++++++++++++- src/mailer/main.vala | 2 +- test/engine/rfc822/rfc822-message-test.vala | 1 + test/integration/smtp/client-session.vala | 1 + 8 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala index 965898e8..eb6e4ce7 100644 --- a/src/client/composer/composer-widget.vala +++ b/src/client/composer/composer-widget.vala @@ -1723,7 +1723,7 @@ public class Composer.Widget : Gtk.EventBox, Geary.BaseInterface { Geary.ComposedEmail draft = yield to_composed_email(null, true); yield this.draft_manager.update( yield new Geary.RFC822.Message.from_composed_email( - draft, null, null + draft, null, GMime.EncodingConstraint.7BIT, null ), null, null diff --git a/src/client/plugin/mail-merge/mail-merge-folder.vala b/src/client/plugin/mail-merge/mail-merge-folder.vala index bd6cafca..16ccf4df 100644 --- a/src/client/plugin/mail-merge/mail-merge-folder.vala +++ b/src/client/plugin/mail-merge/mail-merge-folder.vala @@ -326,7 +326,7 @@ public class MailMerge.Folder : Geary.AbstractLocalFolder { var processor = new Processor(this.template); var composed = processor.merge(fields); var message = yield new Geary.RFC822.Message.from_composed_email( - composed, null, cancellable + composed, null, GMime.EncodingConstraint.7BIT, cancellable ); var id = new EmailIdentifier(next_id++); diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala index 11237023..fde088bf 100644 --- a/src/engine/rfc822/rfc822-message.vala +++ b/src/engine/rfc822/rfc822-message.vala @@ -236,6 +236,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet { public async Message.from_composed_email(Geary.ComposedEmail email, string? message_id, + GMime.EncodingConstraint constraint, GLib.Cancellable? cancellable) throws Error { this.message = new GMime.Message(true); @@ -338,6 +339,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet { null, "text/plain", true, + constraint, cancellable ); } catch (GLib.Error err) { @@ -438,6 +440,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet { body_charset, "text/html", false, + constraint, cancellable ); } catch (GLib.Error err) { @@ -1200,6 +1203,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet { string? charset, string content_type, bool is_flowed, + GMime.EncodingConstraint constraint, GLib.Cancellable? cancellable) throws GLib.Error { GMime.Stream content_stream = new GMime.StreamMem.with_buffer(content); @@ -1211,7 +1215,7 @@ public class Geary.RFC822.Message : BaseObject, EmailHeaderSet { GMime.ContentEncoding encoding = yield Utils.get_best_encoding( filter_stream, - GMime.EncodingConstraint.7BIT, + constraint, cancellable ); diff --git a/src/engine/smtp/smtp-capabilities.vala b/src/engine/smtp/smtp-capabilities.vala index adfc7e19..5da46804 100644 --- a/src/engine/smtp/smtp-capabilities.vala +++ b/src/engine/smtp/smtp-capabilities.vala @@ -12,6 +12,7 @@ public class Geary.Smtp.Capabilities : Geary.GenericCapabilities { public const string AUTH_PLAIN = "plain"; public const string AUTH_LOGIN = "login"; public const string AUTH_OAUTH2 = "xoauth2"; + public const string 8BITMIME = "8bitmime"; public const string NAME_SEPARATOR = " "; public const string VALUE_SEPARATOR = " "; diff --git a/src/engine/smtp/smtp-client-service.vala b/src/engine/smtp/smtp-client-service.vala index 5faaff94..595405a6 100644 --- a/src/engine/smtp/smtp-client-service.vala +++ b/src/engine/smtp/smtp-client-service.vala @@ -120,6 +120,21 @@ public class Geary.Smtp.ClientService : Geary.ClientService { throws GLib.Error { debug("Saving composed email: %s", email_subject(composed)); + // Detect server encoding constraint + GMime.EncodingConstraint constraint = GMime.EncodingConstraint.7BIT; + try { + + ClientConnection smtp = new ClientConnection(this.remote); + yield smtp.connect_async(cancellable); + yield smtp.say_hello_async(cancellable); + if (smtp.capabilities.has_capability(Capabilities.8BITMIME)) { + constraint = GMime.EncodingConstraint.8BIT; + } + yield smtp.disconnect_async(cancellable); + } catch (Error err) { + // Oh well + } + // XXX work out what our public IP address is somehow and use // that in preference to the originator's domain var from = composed.from; @@ -128,7 +143,10 @@ public class Geary.Smtp.ClientService : Geary.ClientService { : this.account.primary_mailbox.domain; Geary.RFC822.Message rfc822 = yield new Geary.RFC822.Message.from_composed_email( - composed, GMime.utils_generate_message_id(domain), cancellable + composed, + GMime.utils_generate_message_id(domain), + constraint, + cancellable ); EmailIdentifier id = yield this.outbox.create_email_async( diff --git a/src/mailer/main.vala b/src/mailer/main.vala index aaaca73f..64e8bdfd 100644 --- a/src/mailer/main.vala +++ b/src/mailer/main.vala @@ -44,7 +44,7 @@ async void main_async() throws Error { } msg = yield new Geary.RFC822.Message.from_composed_email( - composed_email, null, null + composed_email, null, GMime.EncodingConstraint.7BIT, null ); } diff --git a/test/engine/rfc822/rfc822-message-test.vala b/test/engine/rfc822/rfc822-message-test.vala index 57976cca..a1bc5468 100644 --- a/test/engine/rfc822/rfc822-message-test.vala +++ b/test/engine/rfc822/rfc822-message-test.vala @@ -446,6 +446,7 @@ This is the second line. return yield new Geary.RFC822.Message.from_composed_email( composed, GMime.utils_generate_message_id(composed.from.get(0).domain), + GMime.EncodingConstraint.7BIT, null ); } diff --git a/test/integration/smtp/client-session.vala b/test/integration/smtp/client-session.vala index 3d81a5db..9aa9be26 100644 --- a/test/integration/smtp/client-session.vala +++ b/test/integration/smtp/client-session.vala @@ -133,6 +133,7 @@ class Integration.Smtp.ClientSession : TestCase { return yield new Geary.RFC822.Message.from_composed_email( composed, GMime.utils_generate_message_id(from.domain), + GMime.EncodingConstraint.7BIT, null ); }