[geary] RFC822 Sender header cleanup. Bug 768468.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary] RFC822 Sender header cleanup. Bug 768468.
- Date: Mon, 25 Jul 2016 00:41:03 +0000 (UTC)
commit bbf5f073e61283a75097dbe0f9d3db246eed8812
Author: Michael James Gratton <mike vee net>
Date: Wed Jul 6 13:34:48 2016 +1000
RFC822 Sender header cleanup. Bug 768468.
This patch does a few things:
- Removes any notion of a sender from the Composer, since there's no UI
for it at the moment and it doesn't do anything when multiple
addresses are available.
- Converts Geary.Email and the DB use the RFC822 model for the Sender and
Reply-To headers, and translates between that and the IMAP model only
once: When dealing with IMAP ENVELOPE.
- Fixes an incorrect assumption about the Sender in the SMTP code.
* src/client/composer/composer-widget.vala (ComposerWidget): Remove all
mentions of a sender address. Make `from` prop private for setting.
* src/client/composer/email-entry.vala (EmailEntry::validate_addresses):
Fix crash when address list is null.
* src/engine/api/geary-email.vala (Email, Email::set_originators):
Convert sender prop/param from a list of RFC822 addresses to a single
address. Fix call call sites.
* src/engine/imap-db/imap-db-message-addresses.vala (MessageAddresses):
Convert sender prop from a list of RFC822 addresses to a single
address. Fix call call sites.
(MessageAddresses::get_address_from_string): New method for parsing
single addresses from the DB.
* src/engine/imap-db/imap-db-message-row.vala
(MessageRow::flatten_address, MessageRow::unflatten_address): New
un/marshalling methods for single addresses.
* src/engine/imap/api/imap-folder.vala (Folder::fetched_data_to_email):
Normalise sender and reply-to IMAP ENVELOPE responses to conform with
RFC 822's expectations.
* src/engine/imap/message/imap-envelope.vala (Envelope): Label reply_to
prop as being non-null, to conform with IMAP spec.
* src/engine/rfc822/rfc822-mailbox-address.vala (MailboxAddress): Added
support ctor and methods for parsing and comparing single addresses.
* src/engine/rfc822/rfc822-message.vala (Message::from_composed_email):
Set the from and sender props directly from the ComposedEmail, set the
GMimeMessage From and Sender headers correctly based on these.
(Message::stock_from_gmime): Correctly set the from and sender props
from the GMimeMessage.
* src/engine/smtp/smtp-client-session.vala
(ClientSession::send_email_async): Don't require the email sender to be
non-null — it isn't used and isn't required.
src/client/composer/composer-widget.vala | 22 ++---
src/client/composer/email-entry.vala | 2 +-
src/engine/api/geary-email.vala | 39 ++++++---
src/engine/imap-db/imap-db-message-addresses.vala | 48 +++++++----
src/engine/imap-db/imap-db-message-row.vala | 42 +++++++--
src/engine/imap/api/imap-folder.vala | 22 +++--
src/engine/imap/message/imap-envelope.vala | 9 +-
src/engine/rfc822/rfc822-mailbox-address.vala | 25 +++++-
src/engine/rfc822/rfc822-message.vala | 97 ++++++++++++--------
src/engine/smtp/smtp-client-session.vala | 5 +-
10 files changed, 197 insertions(+), 114 deletions(-)
---
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 2472a6e..0387195 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -29,15 +29,13 @@ public class ComposerWidget : Gtk.EventBox {
private class FromAddressMap {
public Geary.Account account;
- public Geary.RFC822.MailboxAddress? sender;
public Geary.RFC822.MailboxAddresses from;
- public FromAddressMap(Geary.Account a, Geary.RFC822.MailboxAddresses f, Geary.RFC822.MailboxAddress?
s = null) {
+ public FromAddressMap(Geary.Account a, Geary.RFC822.MailboxAddresses f) {
account = a;
from = f;
- sender = s;
}
}
-
+
public const string ACTION_UNDO = "undo";
public const string ACTION_REDO = "redo";
public const string ACTION_CUT = "cut";
@@ -140,11 +138,9 @@ public class ComposerWidget : Gtk.EventBox {
private delegate bool CompareStringFunc(string key, string token);
public Geary.Account account { get; private set; }
-
- public Geary.RFC822.MailboxAddress sender { get; set; }
-
- public Geary.RFC822.MailboxAddresses from { get; set; }
-
+
+ public Geary.RFC822.MailboxAddresses from { get; private set; }
+
public string to {
get { return to_entry.get_text(); }
set { to_entry.set_text(value); }
@@ -906,8 +902,7 @@ public class ComposerWidget : Gtk.EventBox {
bool only_html = false) {
Geary.ComposedEmail email = new Geary.ComposedEmail(
date_override ?? new DateTime.now_local(), from);
- email.sender = sender;
-
+
if (to_entry.addresses != null)
email.to = to_entry.addresses;
@@ -2449,13 +2444,12 @@ public class ComposerWidget : Gtk.EventBox {
return false;
assert(from_list.size > index);
-
+
Geary.Account new_account = from_list.get(index).account;
from = from_list.get(index).from;
- sender = from_list.get(index).sender;
if (new_account == account)
return false;
-
+
account = new_account;
set_entry_completions();
diff --git a/src/client/composer/email-entry.vala b/src/client/composer/email-entry.vala
index ba4a157..3f23f20 100644
--- a/src/client/composer/email-entry.vala
+++ b/src/client/composer/email-entry.vala
@@ -55,7 +55,7 @@ public class EmailEntry : Gtk.Entry {
}
private void validate_addresses() {
- if (addresses.size == 0) {
+ if (addresses == null || addresses.size == 0) {
valid_or_empty = true;
empty = true;
return;
diff --git a/src/engine/api/geary-email.vala b/src/engine/api/geary-email.vala
index c068d69..0b2b1f3 100644
--- a/src/engine/api/geary-email.vala
+++ b/src/engine/api/geary-email.vala
@@ -111,12 +111,12 @@ public class Geary.Email : BaseObject {
// DATE
public Geary.RFC822.Date? date { get; private set; default = null; }
-
+
// ORIGINATORS
public Geary.RFC822.MailboxAddresses? from { get; private set; default = null; }
- public Geary.RFC822.MailboxAddresses? sender { get; private set; default = null; }
+ public Geary.RFC822.MailboxAddress? sender { get; private set; default = null; }
public Geary.RFC822.MailboxAddresses? reply_to { get; private set; default = null; }
-
+
// RECEIVERS
public Geary.RFC822.MailboxAddresses? to { get; private set; default = null; }
public Geary.RFC822.MailboxAddresses? cc { get; private set; default = null; }
@@ -172,16 +172,27 @@ public class Geary.Email : BaseObject {
fields |= Field.DATE;
}
-
- public void set_originators(Geary.RFC822.MailboxAddresses? from,
- Geary.RFC822.MailboxAddresses? sender, Geary.RFC822.MailboxAddresses? reply_to) {
+
+ /**
+ * Sets the RFC822 originators for the message.
+ *
+ * RFC 2822 requires at least one From address, that the Sender
+ * and From not be identical, and that both From and ReplyTo are
+ * optional.
+ */
+ public void set_originators(Geary.RFC822.MailboxAddresses from,
+ Geary.RFC822.MailboxAddress? sender,
+ Geary.RFC822.MailboxAddresses? reply_to)
+ throws RFC822Error {
+ // XXX Should be throwing an error here if from is empty or
+ // sender is same as from
this.from = from;
this.sender = sender;
this.reply_to = reply_to;
-
+
fields |= Field.ORIGINATORS;
}
-
+
public void set_receivers(Geary.RFC822.MailboxAddresses? to,
Geary.RFC822.MailboxAddresses? cc, Geary.RFC822.MailboxAddresses? bcc) {
this.to = to;
@@ -329,16 +340,16 @@ public class Geary.Email : BaseObject {
public RFC822.MailboxAddress? get_primary_originator() {
if (from != null && from.size > 0)
return from[0];
-
- if (sender != null && sender.size > 0)
- return sender[0];
-
+
+ if (sender != null)
+ return sender;
+
if (reply_to != null && reply_to.size > 0)
return reply_to[0];
-
+
return null;
}
-
+
public string to_string() {
return "[%s] ".printf(id.to_string());
}
diff --git a/src/engine/imap-db/imap-db-message-addresses.vala
b/src/engine/imap-db/imap-db-message-addresses.vala
index 7800b09..d260bdc 100644
--- a/src/engine/imap-db/imap-db-message-addresses.vala
+++ b/src/engine/imap-db/imap-db-message-addresses.vala
@@ -8,7 +8,7 @@ private class Geary.ImapDB.MessageAddresses : BaseObject {
// Read-only view.
public Gee.Collection<Contact> contacts { get; private set; }
- private RFC822.MailboxAddresses? sender_addresses;
+ private RFC822.MailboxAddress? sender_address;
private RFC822.MailboxAddresses? from_addresses;
private RFC822.MailboxAddresses? to_addresses;
private RFC822.MailboxAddresses? cc_addresses;
@@ -17,11 +17,11 @@ private class Geary.ImapDB.MessageAddresses : BaseObject {
private int from_importance;
private int to_importance;
private int cc_importance;
-
- private MessageAddresses(string account_owner_email, RFC822.MailboxAddresses? sender_addresses,
+
+ private MessageAddresses(string account_owner_email, RFC822.MailboxAddress? sender_address,
RFC822.MailboxAddresses? from_addresses, RFC822.MailboxAddresses? to_addresses,
RFC822.MailboxAddresses? cc_addresses, RFC822.MailboxAddresses? bcc_addresses) {
- this.sender_addresses = sender_addresses;
+ this.sender_address = sender_address;
this.from_addresses = from_addresses;
this.to_addresses = to_addresses;
this.cc_addresses = cc_addresses;
@@ -33,7 +33,7 @@ private class Geary.ImapDB.MessageAddresses : BaseObject {
private MessageAddresses.from_strings(string account_owner_email, string? sender_field,
string? from_field, string? to_field, string? cc_field, string? bcc_field) {
- this(account_owner_email, get_addresses_from_string(sender_field),
+ this(account_owner_email, get_address_from_string(sender_field),
get_addresses_from_string(from_field), get_addresses_from_string(to_field),
get_addresses_from_string(cc_field), get_addresses_from_string(bcc_field));
}
@@ -60,15 +60,27 @@ private class Geary.ImapDB.MessageAddresses : BaseObject {
return null;
}
}
-
+
+ private static RFC822.MailboxAddress? get_address_from_string(string? field) {
+ RFC822.MailboxAddress? addr = null;
+ if (field != null) {
+ try {
+ new RFC822.MailboxAddress.from_rfc822_string(field);
+ } catch (RFC822Error e) {
+ // oh well
+ }
+ }
+ return addr;
+ }
+
private static RFC822.MailboxAddresses? get_addresses_from_string(string? field) {
return field == null ? null : new RFC822.MailboxAddresses.from_rfc822_string(field);
}
-
+
private void calculate_importance(string account_owner_email) {
// "Sender" is different than "from", but we give it the same importance.
bool account_owner_in_from =
- (sender_addresses != null && sender_addresses.contains_normalized(account_owner_email)) ||
+ (sender_address != null && sender_address.equal_normalized(account_owner_email)) ||
(from_addresses != null && from_addresses.contains_normalized(account_owner_email));
bool account_owner_in_to = to_addresses != null &&
to_addresses.contains_normalized(account_owner_email);
@@ -102,19 +114,21 @@ private class Geary.ImapDB.MessageAddresses : BaseObject {
cc_importance = int.max(cc_importance, ContactImportance.CC_CC);
}
}
-
+
private Gee.Collection<Contact> build_contacts() {
Gee.Map<string, Contact> contacts_map = new Gee.HashMap<string, Contact>();
-
- add_contacts(contacts_map, sender_addresses, from_importance);
- add_contacts(contacts_map, from_addresses, from_importance);
- add_contacts(contacts_map, to_addresses, to_importance);
- add_contacts(contacts_map, cc_addresses, cc_importance);
- add_contacts(contacts_map, bcc_addresses, cc_importance);
-
+
+ if (this.sender_address != null) {
+ add_contact(contacts_map, this.sender_address, this.from_importance);
+ }
+ add_contacts(contacts_map, this.from_addresses, this.from_importance);
+ add_contacts(contacts_map, this.to_addresses, this.to_importance);
+ add_contacts(contacts_map, this.cc_addresses, this.cc_importance);
+ add_contacts(contacts_map, this.bcc_addresses, this.cc_importance);
+
return contacts_map.values;
}
-
+
private void add_contacts(Gee.Map<string, Contact> contacts_map, RFC822.MailboxAddresses? addresses,
int importance) {
if (addresses == null)
diff --git a/src/engine/imap-db/imap-db-message-row.vala b/src/engine/imap-db/imap-db-message-row.vala
index 291b83c..c27e755 100644
--- a/src/engine/imap-db/imap-db-message-row.vala
+++ b/src/engine/imap-db/imap-db-message-row.vala
@@ -105,17 +105,19 @@ private class Geary.ImapDB.MessageRow {
if (fields.is_all_set(Geary.Email.Field.DATE))
email.set_send_date(!String.is_empty(date) ? new RFC822.Date(date) : null);
-
+
if (fields.is_all_set(Geary.Email.Field.ORIGINATORS)) {
- email.set_originators(unflatten_addresses(from), unflatten_addresses(sender),
- unflatten_addresses(reply_to));
+ email.set_originators(unflatten_addresses(from),
+ unflatten_address(sender),
+ unflatten_addresses(reply_to));
}
-
+
if (fields.is_all_set(Geary.Email.Field.RECEIVERS)) {
- email.set_receivers(unflatten_addresses(to), unflatten_addresses(cc),
- unflatten_addresses(bcc));
+ email.set_receivers(unflatten_addresses(to),
+ unflatten_addresses(cc),
+ unflatten_addresses(bcc));
}
-
+
if (fields.is_all_set(Geary.Email.Field.REFERENCES)) {
email.set_full_references(
(message_id != null) ? new RFC822.MessageID(message_id) : null,
@@ -188,7 +190,7 @@ private class Geary.ImapDB.MessageRow {
if (email.fields.is_all_set(Geary.Email.Field.ORIGINATORS)) {
from = flatten_addresses(email.from);
- sender = flatten_addresses(email.sender);
+ sender = flatten_address(email.sender);
reply_to = flatten_addresses(email.reply_to);
fields = fields.set(Geary.Email.Field.ORIGINATORS);
@@ -250,7 +252,15 @@ private class Geary.ImapDB.MessageRow {
fields = fields.set(Geary.Email.Field.PROPERTIES);
}
}
-
+
+ private static string? flatten_address(RFC822.MailboxAddress? addr) {
+ string? flat = null;
+ if (addr != null) {
+ flat = addr.to_rfc822_string();
+ }
+ return flat;
+ }
+
private static string? flatten_addresses(RFC822.MailboxAddresses? addrs) {
if (addrs == null)
return null;
@@ -274,7 +284,19 @@ private class Geary.ImapDB.MessageRow {
return builder.str;
}
}
-
+
+ private RFC822.MailboxAddress? unflatten_address(string? str) {
+ RFC822.MailboxAddress? addr = null;
+ if (str != null) {
+ try {
+ addr = new RFC822.MailboxAddress.from_rfc822_string(str);
+ } catch (RFC822Error e) {
+ // oh well
+ }
+ }
+ return addr;
+ }
+
private RFC822.MailboxAddresses? unflatten_addresses(string? str) {
return String.is_empty(str) ? null : new RFC822.MailboxAddresses.from_rfc822_string(str);
}
diff --git a/src/engine/imap/api/imap-folder.vala b/src/engine/imap/api/imap-folder.vala
index f7358c9..a15a366 100644
--- a/src/engine/imap/api/imap-folder.vala
+++ b/src/engine/imap/api/imap-folder.vala
@@ -848,12 +848,16 @@ private class Geary.Imap.Folder : BaseObject {
switch (data_type) {
case FetchDataSpecifier.ENVELOPE:
Envelope envelope = (Envelope) data;
-
+
email.set_send_date(envelope.sent);
email.set_message_subject(envelope.subject);
- email.set_originators(envelope.from, envelope.sender, envelope.reply_to);
+ email.set_originators(
+ envelope.from,
+ envelope.sender.equal_to(envelope.from) ? null : envelope.sender[0],
+ envelope.reply_to.equal_to(envelope.from) ? null : envelope.reply_to
+ );
email.set_receivers(envelope.to, envelope.cc, envelope.bcc);
-
+
// store these to add to References all at once
message_id = envelope.message_id;
in_reply_to = envelope.in_reply_to;
@@ -915,20 +919,20 @@ private class Geary.Imap.Folder : BaseObject {
string? value = headers.get_header("From");
if (!String.is_empty(value))
from = new RFC822.MailboxAddresses.from_rfc822_string(value);
-
- RFC822.MailboxAddresses? sender = null;
+
+ RFC822.MailboxAddress? sender = null;
value = headers.get_header("Sender");
if (!String.is_empty(value))
- sender = new RFC822.MailboxAddresses.from_rfc822_string(value);
-
+ sender = new RFC822.MailboxAddress.from_rfc822_string(value);
+
RFC822.MailboxAddresses? reply_to = null;
value = headers.get_header("Reply-To");
if (!String.is_empty(value))
reply_to = new RFC822.MailboxAddresses.from_rfc822_string(value);
-
+
email.set_originators(from, sender, reply_to);
}
-
+
// RECEIVERS
if (required_but_not_set(Geary.Email.Field.RECEIVERS, required_fields, email)) {
RFC822.MailboxAddresses? to = null;
diff --git a/src/engine/imap/message/imap-envelope.vala b/src/engine/imap/message/imap-envelope.vala
index 5a471de..1d6b26d 100644
--- a/src/engine/imap/message/imap-envelope.vala
+++ b/src/engine/imap/message/imap-envelope.vala
@@ -15,16 +15,16 @@ public class Geary.Imap.Envelope : Geary.MessageData.AbstractMessageData, Geary.
public Geary.RFC822.Subject subject { get; private set; }
public Geary.RFC822.MailboxAddresses from { get; private set; }
public Geary.RFC822.MailboxAddresses sender { get; private set; }
- public Geary.RFC822.MailboxAddresses? reply_to { get; private set; }
+ public Geary.RFC822.MailboxAddresses reply_to { get; private set; }
public Geary.RFC822.MailboxAddresses? to { get; private set; }
public Geary.RFC822.MailboxAddresses? cc { get; private set; }
public Geary.RFC822.MailboxAddresses? bcc { get; private set; }
public Geary.RFC822.MessageIDList? in_reply_to { get; private set; }
public Geary.RFC822.MessageID? message_id { get; private set; }
-
+
public Envelope(Geary.RFC822.Date? sent, Geary.RFC822.Subject subject,
Geary.RFC822.MailboxAddresses from, Geary.RFC822.MailboxAddresses sender,
- Geary.RFC822.MailboxAddresses? reply_to, Geary.RFC822.MailboxAddresses? to,
+ Geary.RFC822.MailboxAddresses reply_to, Geary.RFC822.MailboxAddresses? to,
Geary.RFC822.MailboxAddresses? cc, Geary.RFC822.MailboxAddresses? bcc,
Geary.RFC822.MessageIDList? in_reply_to, Geary.RFC822.MessageID? message_id) {
this.sent = sent;
@@ -38,10 +38,9 @@ public class Geary.Imap.Envelope : Geary.MessageData.AbstractMessageData, Geary.
this.in_reply_to = in_reply_to;
this.message_id = message_id;
}
-
+
public override string to_string() {
return "[%s] %s: \"%s\"".printf((sent != null) ? sent.to_string() : "(no date)",
from.to_string(), subject.to_string());
}
}
-
diff --git a/src/engine/rfc822/rfc822-mailbox-address.vala b/src/engine/rfc822/rfc822-mailbox-address.vala
index 83fd1e8..1c3af97 100644
--- a/src/engine/rfc822/rfc822-mailbox-address.vala
+++ b/src/engine/rfc822/rfc822-mailbox-address.vala
@@ -72,6 +72,25 @@ public class Geary.RFC822.MailboxAddress : Geary.MessageData.SearchableMessageDa
address = "%s@%s".printf(mailbox, domain);
}
+ public MailboxAddress.from_rfc822_string(string rfc822) throws RFC822Error {
+ InternetAddressList addrlist = InternetAddressList.parse_string(rfc822);
+ if (addrlist == null)
+ return;
+
+ int length = addrlist.length();
+ for (int ctr = 0; ctr < length; ctr++) {
+ InternetAddress? addr = addrlist.get_address(ctr);
+
+ // TODO: Handle group lists
+ InternetAddressMailbox? mbox_addr = addr as InternetAddressMailbox;
+ if (mbox_addr != null) {
+ this(mbox_addr.get_name(), mbox_addr.get_addr());
+ return;
+ }
+ }
+ throw new RFC822Error.INVALID("Could not parse RFC822 address: %s", rfc822);
+ }
+
// Borrowed liberally from GMime's internal _internet_address_decode_name() function.
private static string decode_name(string name) {
// see if a broken mailer has sent raw 8-bit information
@@ -181,7 +200,11 @@ public class Geary.RFC822.MailboxAddress : Geary.MessageData.SearchableMessageDa
public bool equal_to(MailboxAddress other) {
return this != other ? String.stri_equal(address, other.address) : true;
}
-
+
+ public bool equal_normalized(string address) {
+ return this.address.normalize().casefold() == address.normalize().casefold();
+ }
+
public string to_string() {
return get_full_address();
}
diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala
index 856716a..aca8bfb 100644
--- a/src/engine/rfc822/rfc822-message.vala
+++ b/src/engine/rfc822/rfc822-message.vala
@@ -17,7 +17,8 @@ public class Geary.RFC822.Message : BaseObject {
Mime.ContentDisposition? disposition, string? content_id, Geary.Memory.Buffer buffer);
private const string DEFAULT_ENCODING = "UTF8";
-
+
+ private const string HEADER_SENDER = "Sender";
private const string HEADER_IN_REPLY_TO = "In-Reply-To";
private const string HEADER_REFERENCES = "References";
private const string HEADER_MAILER = "X-Mailer";
@@ -85,61 +86,70 @@ public class Geary.RFC822.Message : BaseObject {
}
public Message.from_composed_email(Geary.ComposedEmail email, string? message_id) {
- message = new GMime.Message(true);
-
+ this.message = new GMime.Message(true);
+
// Required headers
assert(email.from.size > 0);
- sender = email.from[0];
- date = new RFC822.Date.from_date_time(email.date);
-
- message.set_sender(sender.to_rfc822_string());
- message.set_date_as_string(date.serialize());
+ this.sender = email.sender;
+ this.from = email.from;
+ this.date = new RFC822.Date.from_date_time(email.date);
+
+ // GMimeMessage.set_sender actually sets the From header - and
+ // although the API docs make it sound otherwise, it also
+ // supports a list of addresses
+ message.set_sender(this.from.to_rfc822_string());
+ message.set_date_as_string(this.date.serialize());
if (message_id != null)
message.set_message_id(message_id);
-
+
// Optional headers
if (email.to != null) {
- to = email.to;
+ this.to = email.to;
foreach (RFC822.MailboxAddress mailbox in email.to)
- message.add_recipient(GMime.RecipientType.TO, mailbox.name, mailbox.address);
+ this.message.add_recipient(GMime.RecipientType.TO, mailbox.name, mailbox.address);
}
-
+
if (email.cc != null) {
- cc = email.cc;
+ this.cc = email.cc;
foreach (RFC822.MailboxAddress mailbox in email.cc)
- message.add_recipient(GMime.RecipientType.CC, mailbox.name, mailbox.address);
+ this.message.add_recipient(GMime.RecipientType.CC, mailbox.name, mailbox.address);
}
if (email.bcc != null) {
- bcc = email.bcc;
+ this.bcc = email.bcc;
foreach (RFC822.MailboxAddress mailbox in email.bcc)
- message.add_recipient(GMime.RecipientType.BCC, mailbox.name, mailbox.address);
+ this.message.add_recipient(GMime.RecipientType.BCC, mailbox.name, mailbox.address);
+ }
+
+ if (email.sender != null) {
+ this.sender = email.sender;
+ this.message.set_header(HEADER_SENDER, email.sender.to_rfc822_string());
}
if (email.reply_to != null) {
- reply_to = email.reply_to;
- message.set_reply_to(email.reply_to.to_rfc822_string());
+ this.reply_to = email.reply_to;
+ this.message.set_reply_to(email.reply_to.to_rfc822_string());
}
if (email.in_reply_to != null) {
- in_reply_to = new Geary.RFC822.MessageIDList.from_rfc822_string(email.in_reply_to);
- message.set_header(HEADER_IN_REPLY_TO, email.in_reply_to);
+ this.in_reply_to = new Geary.RFC822.MessageIDList.from_rfc822_string(email.in_reply_to);
+ this.message.set_header(HEADER_IN_REPLY_TO, email.in_reply_to);
}
-
+
if (email.references != null) {
- references = new Geary.RFC822.MessageIDList.from_rfc822_string(email.references);
- message.set_header(HEADER_REFERENCES, email.references);
+ this.references = new Geary.RFC822.MessageIDList.from_rfc822_string(email.references);
+ this.message.set_header(HEADER_REFERENCES, email.references);
}
-
+
if (email.subject != null) {
- subject = new Geary.RFC822.Subject(email.subject);
- message.set_subject(email.subject);
+ this.subject = new Geary.RFC822.Subject(email.subject);
+ this.message.set_subject(email.subject);
}
// User-Agent
if (!Geary.String.is_empty(email.mailer)) {
- mailer = email.mailer;
- message.set_header(HEADER_MAILER, email.mailer);
+ this.mailer = email.mailer;
+ this.message.set_header(HEADER_MAILER, email.mailer);
}
// Body: text format (optional)
@@ -201,11 +211,11 @@ public class Geary.RFC822.Message : BaseObject {
GMime.Object? attachment_part = coalesce_parts(attachment_parts, "mixed");
if (attachment_part != null)
main_parts.add(attachment_part);
-
+
GMime.Object? main_part = coalesce_parts(main_parts, "mixed");
- message.set_mime_part(main_part);
+ this.message.set_mime_part(main_part);
}
-
+
// Makes a copy of the given message without the BCC fields. This is used for sending the email
// without sending the BCC headers to all recipients.
public Message.without_bcc(Message email) {
@@ -296,7 +306,7 @@ public class Geary.RFC822.Message : BaseObject {
email.set_message_header(new Geary.RFC822.Header(new Geary.Memory.StringBuffer(
message.get_headers())));
email.set_send_date(date);
- email.set_originators(from, new Geary.RFC822.MailboxAddresses.single(sender), reply_to);
+ email.set_originators(from, sender, reply_to);
email.set_receivers(to, cc, bcc);
email.set_full_references(null, in_reply_to, references);
email.set_message_subject(subject);
@@ -326,13 +336,25 @@ public class Geary.RFC822.Message : BaseObject {
}
private void stock_from_gmime() {
+ // GMime calls the From address the "sender"
string? message_sender = message.get_sender();
if (message_sender != null) {
- from = new RFC822.MailboxAddresses.from_rfc822_string(message_sender);
- // sender is defined as first From address, from better or worse
- sender = (from.size != 0) ? from[0] : null;
+ this.from = new RFC822.MailboxAddresses.from_rfc822_string(message_sender);
}
-
+
+ // And it doesn't provide a convenience method for Sender header
+ if (!String.is_empty(message.get_header(HEADER_SENDER))) {
+ string sender = GMime.utils_header_decode_text(message.get_header(HEADER_SENDER));
+ try {
+ this.sender = new RFC822.MailboxAddress.from_rfc822_string(sender);
+ } catch (RFC822Error e) {
+ debug("Invalid RDC822 Sender address: %s", sender);
+ }
+ }
+
+ if (!String.is_empty(message.get_reply_to()))
+ this.reply_to = new RFC822.MailboxAddresses.from_rfc822_string(message.get_reply_to());
+
Gee.List<RFC822.MailboxAddress>? converted = convert_gmime_address_list(
message.get_recipients(GMime.RecipientType.TO));
if (converted != null && converted.size > 0)
@@ -346,9 +368,6 @@ public class Geary.RFC822.Message : BaseObject {
if (converted != null && converted.size > 0)
bcc = new RFC822.MailboxAddresses(converted);
- if (!String.is_empty(message.get_reply_to()))
- reply_to = new RFC822.MailboxAddresses.from_rfc822_string(message.get_reply_to());
-
if (!String.is_empty(message.get_header(HEADER_IN_REPLY_TO)))
in_reply_to = new
RFC822.MessageIDList.from_rfc822_string(message.get_header(HEADER_IN_REPLY_TO));
diff --git a/src/engine/smtp/smtp-client-session.vala b/src/engine/smtp/smtp-client-session.vala
index ac67386..de62233 100644
--- a/src/engine/smtp/smtp-client-session.vala
+++ b/src/engine/smtp/smtp-client-session.vala
@@ -146,11 +146,8 @@ public class Geary.Smtp.ClientSession {
rset_required = false;
}
-
+
// MAIL
- if (email.sender == null)
- throw new SmtpError.REQUIRED_FIELD("No sender in message");
-
MailRequest mail_request = new MailRequest(from);
Response response = yield cx.transaction_async(mail_request, cancellable);
if (!response.code.is_success_completed())
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]