am 5057d6df: Replying to a Message with an encoded email address shows the encoded address in the to field.

* commit '5057d6dffb994b4d1d02c05e06f679de8ef05ea5':
  Replying to a Message with an encoded email address shows the encoded address in the to field.
This commit is contained in:
James Lemieux 2014-04-02 22:56:50 +00:00 committed by Android Git Automerger
commit 1d074abc2c
6 changed files with 277 additions and 166 deletions

View File

@ -78,7 +78,7 @@ public class LegacyConversions {
* Copy field-by-field from a "store" message to a "provider" message
* @param message The message we've just downloaded (must be a MimeMessage)
* @param localMessage The message we'd like to write into the DB
* @result true if dirty (changes were made)
* @return true if dirty (changes were made)
*/
public static boolean updateMessageFields(EmailContent.Message localMessage, Message message,
long accountId, long mailboxId) throws MessagingException {
@ -130,7 +130,7 @@ public class LegacyConversions {
// Only replace the local message-id if a new one was found. This is seen in some ISP's
// which may deliver messages w/o a message-id header.
String messageId = ((MimeMessage)message).getMessageId();
String messageId = message.getMessageId();
if (messageId != null) {
localMessage.mMessageId = messageId;
}
@ -140,13 +140,13 @@ public class LegacyConversions {
localMessage.mAccountKey = accountId;
if (from != null && from.length > 0) {
localMessage.mFrom = Address.toHeader(from);
localMessage.mFrom = Address.toString(from);
}
localMessage.mTo = Address.toHeader(to);
localMessage.mCc = Address.toHeader(cc);
localMessage.mBcc = Address.toHeader(bcc);
localMessage.mReplyTo = Address.toHeader(replyTo);
localMessage.mTo = Address.toString(to);
localMessage.mCc = Address.toString(cc);
localMessage.mBcc = Address.toString(bcc);
localMessage.mReplyTo = Address.toString(replyTo);
// public String mText;
// public String mHtml;

View File

@ -175,7 +175,8 @@ public final class DBHelper {
// exchange accounts.
// Version 124: Added MAX_ATTACHMENT_SIZE to the account table
// Version 125: Add credentials table for OAuth.
public static final int DATABASE_VERSION = 125;
// Version 126: Decode address lists for To, From, Cc, Bcc and Reply-To columns in Message.
public static final int DATABASE_VERSION = 126;
// Any changes to the database format *must* include update-in-place code.
// Original version: 2
@ -1365,6 +1366,10 @@ public final class DBHelper {
db.execSQL("update " + HostAuth.TABLE_NAME + " set "
+ HostAuthColumns.CREDENTIAL_KEY + "=-1");
}
if (oldVersion <= 125) {
upgradeFromVersion125ToVersion126(db);
}
}
@Override
@ -1675,6 +1680,32 @@ public final class DBHelper {
}
}
private static void upgradeFromVersion125ToVersion126(SQLiteDatabase db) {
try {
// Loop through all messages, updating address columns to their decoded form
Cursor messageCursor = db.query(Message.TABLE_NAME, Message.CONTENT_PROJECTION, null,
null, null, null, null);
ContentValues cv = new ContentValues();
String[] whereArgs = new String[1];
try {
while (messageCursor.moveToNext()) {
for (int i = 0; i < ADDRESS_COLUMN_INDICES.length; i++) {
Address[] addrs =
Address.fromHeader(messageCursor.getString(ADDRESS_COLUMN_INDICES[i]));
cv.put(ADDRESS_COLUMN_NAMES[i], Address.toString(addrs));
}
whereArgs[0] = messageCursor.getString(Message.CONTENT_ID_COLUMN);
db.update(Message.TABLE_NAME, cv, WHERE_ID, whereArgs);
}
} finally {
messageCursor.close();
}
} catch (SQLException e) {
// Shouldn't be needed unless we're debugging and interrupt the process
LogUtils.w(TAG, "Exception upgrading EmailProvider.db from 124 to 125 " + e);
}
}
private static void upgradeToEmail2(SQLiteDatabase db) {
// Perform cleanup operations from Email1 to Email2; Email1 will have added new
// data that won't conform to what's expected in Email2

View File

@ -843,6 +843,7 @@ public class EmailProvider extends ContentProvider {
case UPDATED_MESSAGE:
case DELETED_MESSAGE:
case MESSAGE:
decodeEmailAddresses(values);
case BODY:
case ATTACHMENT:
case MAILBOX:
@ -1910,6 +1911,7 @@ public class EmailProvider extends ContentProvider {
}
break;
case MESSAGE:
decodeEmailAddresses(values);
case UPDATED_MESSAGE:
case ATTACHMENT:
case MAILBOX:
@ -5641,6 +5643,43 @@ public class EmailProvider extends ContentProvider {
return 1;
}
/**
* The method will no longer be needed after Kitkat MR2 releases. As emails are received from
* various protocols the email addresses are decoded and intended to be stored in the database
* in decoded form. The problem is that Exchange is a separate .apk and the old Exchange .apk
* still attempts to store <strong>encoded</strong> email addresses. So, we decode here at the
* Provider before writing to the database to ensure the addresses are written in decoded form.
*
* @param values the values to be written into the Message table
*/
private static void decodeEmailAddresses(ContentValues values) {
if (values.containsKey(Message.MessageColumns.TO_LIST)) {
final String to = values.getAsString(Message.MessageColumns.TO_LIST);
values.put(Message.MessageColumns.TO_LIST, Address.fromHeaderToString(to));
}
if (values.containsKey(Message.MessageColumns.FROM_LIST)) {
final String from = values.getAsString(Message.MessageColumns.FROM_LIST);
values.put(Message.MessageColumns.FROM_LIST, Address.fromHeaderToString(from));
}
if (values.containsKey(Message.MessageColumns.CC_LIST)) {
final String cc = values.getAsString(Message.MessageColumns.CC_LIST);
values.put(Message.MessageColumns.CC_LIST, Address.fromHeaderToString(cc));
}
if (values.containsKey(Message.MessageColumns.BCC_LIST)) {
final String bcc = values.getAsString(Message.MessageColumns.BCC_LIST);
values.put(Message.MessageColumns.BCC_LIST, Address.fromHeaderToString(bcc));
}
if (values.containsKey(Message.MessageColumns.REPLY_TO_LIST)) {
final String replyTo = values.getAsString(Message.MessageColumns.REPLY_TO_LIST);
values.put(Message.MessageColumns.REPLY_TO_LIST,
Address.fromHeaderToString(replyTo));
}
}
/** Projection used for getting email address for an account. */
private static final String[] ACCOUNT_EMAIL_PROJECTION = { AccountColumns.EMAIL_ADDRESS };

View File

@ -0,0 +1,190 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.email;
import android.test.AndroidTestCase;
import com.android.emailcommon.internet.MimeBodyPart;
import com.android.emailcommon.internet.MimeMessage;
import com.android.emailcommon.mail.Address;
import com.android.emailcommon.mail.Message.RecipientType;
import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.mail.Part;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.utility.ConversionUtilities;
import com.android.emailcommon.utility.ConversionUtilities.BodyFieldData;
import java.util.ArrayList;
import java.util.Date;
public class LegacyConversionsTest extends AndroidTestCase {
/**
* Test basic fields conversion from Store message to Provider message.
*/
public void testUpdateMessageFields_Basic() throws MessagingException {
final MimeMessage message = new MimeMessage();
message.setUid("UID.12345678");
message.setSentDate(new Date(1));
message.setMessageId("Test-Message-ID");
message.setSubject("This is the subject");
final EmailContent.Message localMessage = new EmailContent.Message();
final boolean result = LegacyConversions.updateMessageFields(localMessage, message, 1, 1);
assertTrue(result);
assertEquals(message.getUid(), localMessage.mServerId);
assertEquals(message.getSubject(), localMessage.mSubject);
assertEquals(message.getMessageId(), localMessage.mMessageId);
assertEquals(message.getSentDate().getTime(), localMessage.mTimeStamp);
}
/**
* Test the conversion of plain ASCII (not MIME-encoded) email addresses.
*/
public void testUpdateMessageFields_PlainAddresses() throws MessagingException {
// create plain ASCII email addresses
final String fromList = "Sender <sender@droid.com>";
final String replyToList = "Reply1 <reply1@droid.com>,Reply2 <reply2@droid.com>";
final String toList = "ToA <toA@droid.com>,ToB <toB@droid.com>";
final String ccList = "CcA <ccA@droid.com>,CcB <ccB@droid.com>";
final String bccList = "BccA <bccA@droid.com>,Bcc2 <bccB@droid.com>";
// parse the addresses
final Address from = Address.fromHeader(fromList)[0];
final Address[] replies = Address.fromHeader(replyToList);
final Address[] tos = Address.fromHeader(toList);
final Address[] ccs = Address.fromHeader(ccList);
final Address[] bccs = Address.fromHeader(bccList);
// make a message with the email addresses
final MimeMessage message = new MimeMessage();
message.setFrom(from);
message.setReplyTo(replies);
message.setRecipients(RecipientType.TO, tos);
message.setRecipients(RecipientType.CC, ccs);
message.setRecipients(RecipientType.BCC, bccs);
// convert the message to a local message using the conversation method
final EmailContent.Message localMessage = new EmailContent.Message();
final boolean result = LegacyConversions.updateMessageFields(localMessage, message, 1, 1);
assertTrue(result);
// verify that we will store the email addresses in decoded form
assertEquals(fromList, localMessage.mFrom);
assertEquals(replyToList, localMessage.mReplyTo);
assertEquals(toList, localMessage.mTo);
assertEquals(ccList, localMessage.mCc);
assertEquals(bccList, localMessage.mBcc);
}
/**
* Test the conversion of MIME-encoded non-ASCII email addresses.
*/
public void testUpdateMessageFields_EncodedAddresses() throws MessagingException {
final String e = "=?EUC-KR?B?uvG50Ln4yKO4pg==?="; // Mime Encoded value of 비밀번호를
final String d = "\uBE44\uBC00\uBC88\uD638\uB97C"; // Mime Decoded value of e
// create the email address in encoded form
String fromList = String.format("%s <sender@droid.com>", e);
String replyToList = String.format("%s <reply1@droid.com>,%s <reply2@droid.com>", e, e);
String toList = String.format("%s <toA@droid.com>,%s <toB@droid.com>", e, e);
String ccList = String.format("%s <ccA@droid.com>,%s <ccB@droid.com>", e, e);
String bccList = String.format("%s <bccA@droid.com>,%s <bccB@droid.com>", e, e);
// parse the encoded addresses
final Address from = Address.fromHeader(fromList)[0];
final Address[] replies = Address.fromHeader(replyToList);
final Address[] tos = Address.fromHeader(toList);
final Address[] ccs = Address.fromHeader(ccList);
final Address[] bccs = Address.fromHeader(bccList);
// make a message with the email addresses
final MimeMessage message = new MimeMessage();
message.setFrom(from);
message.setReplyTo(replies);
message.setRecipients(RecipientType.TO, tos);
message.setRecipients(RecipientType.CC, ccs);
message.setRecipients(RecipientType.BCC, bccs);
// convert the message to a local message using the conversion method
final EmailContent.Message localMessage = new EmailContent.Message();
final boolean result = LegacyConversions.updateMessageFields(localMessage, message, 1, 1);
assertTrue(result);
// verify that we will store the email addresses in decoded form
String decodedFrom = String.format("%s <sender@droid.com>", d);
String decodedReply = String.format("%s <reply1@droid.com>,%s <reply2@droid.com>", d, d);
String decodedTo = String.format("%s <toA@droid.com>,%s <toB@droid.com>", d, d);
String decodedCc = String.format("%s <ccA@droid.com>,%s <ccB@droid.com>", d, d);
String decodedBcc = String.format("%s <bccA@droid.com>,%s <bccB@droid.com>", d, d);
assertEquals(decodedFrom, localMessage.mFrom);
assertEquals(decodedReply, localMessage.mReplyTo);
assertEquals(decodedTo, localMessage.mTo);
assertEquals(decodedCc, localMessage.mCc);
assertEquals(decodedBcc, localMessage.mBcc);
}
/**
* Test basic conversion from Store message to Provider message, when the provider message
* does not have a proper message-id.
*/
public void testUpdateMessageFields_NoMessageId() throws MessagingException {
final MimeMessage message = new MimeMessage();
// set, then remove the message id
message.setMessageId("Test-Message-ID");
message.removeHeader("Message-ID");
// create a local message with an ID
final EmailContent.Message localMessage = new EmailContent.Message();
localMessage.mMessageId = "Test-Message-ID-Second";
final boolean result = LegacyConversions.updateMessageFields(localMessage, message, 1, 1);
assertTrue(result);
assertEquals("Test-Message-ID-Second", localMessage.mMessageId);
}
/**
* Basic test of body parts conversion from Store message to Provider message.
* This tests that a null body part simply results in null text, and does not crash
* or return "null".
*/
public void testUpdateBodyFieldsNullText() throws MessagingException {
ArrayList<Part> viewables = new ArrayList<Part>();
viewables.add(new MimeBodyPart(null, "text/plain"));
// a "null" body part of type text/plain should result in a null mTextContent
final BodyFieldData data = ConversionUtilities.parseBodyFields(viewables);
assertNull(data.textContent);
}
public void testStringNotEqual() {
// Pairs that are "equal"
assertFalse(LegacyConversions.stringNotEqual(null, null));
assertFalse(LegacyConversions.stringNotEqual(null, ""));
assertFalse(LegacyConversions.stringNotEqual("", null));
assertFalse(LegacyConversions.stringNotEqual("", ""));
assertFalse(LegacyConversions.stringNotEqual("string-equal", "string-equal"));
// Pairs that are "inequal"
assertTrue(LegacyConversions.stringNotEqual(null, "string-inequal"));
assertTrue(LegacyConversions.stringNotEqual("", "string-inequal"));
assertTrue(LegacyConversions.stringNotEqual("string-inequal", null));
assertTrue(LegacyConversions.stringNotEqual("string-inequal", ""));
assertTrue(LegacyConversions.stringNotEqual("string-inequal-a", "string-inequal-b"));
}
}

View File

@ -25,11 +25,8 @@ import android.test.suitebuilder.annotation.Suppress;
import com.android.email.provider.EmailProvider;
import com.android.email.provider.ProviderTestUtils;
import com.android.emailcommon.internet.MimeBodyPart;
import com.android.emailcommon.internet.MimeHeader;
import com.android.emailcommon.internet.MimeMessage;
import com.android.emailcommon.internet.MimeUtility;
import com.android.emailcommon.internet.TextBody;
import com.android.emailcommon.mail.Address;
import com.android.emailcommon.mail.BodyPart;
import com.android.emailcommon.mail.Flag;
@ -42,12 +39,9 @@ import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.mail.Part;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Attachment;
import com.android.emailcommon.utility.ConversionUtilities;
import com.android.emailcommon.utility.ConversionUtilities.BodyFieldData;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
/**
* Tests of the Legacy Conversions code (used by MessagingController).
@ -62,20 +56,8 @@ import java.util.Date;
@Suppress
public class LegacyConversionsTests extends ProviderTestCase2<EmailProvider> {
private static final String UID = "UID.12345678";
private static final String SENDER = "sender@android.com";
private static final String RECIPIENT_TO = "recipient-to@android.com";
private static final String RECIPIENT_CC = "recipient-cc@android.com";
private static final String RECIPIENT_BCC = "recipient-bcc@android.com";
private static final String REPLY_TO = "reply-to@android.com";
private static final String SUBJECT = "This is the subject";
private static final String MESSAGE_ID = "Test-Message-ID";
private static final String MESSAGE_ID_2 = "Test-Message-ID-Second";
EmailProvider mProvider;
Context mProviderContext;
Context mContext;
Preferences mPreferences = null;
public LegacyConversionsTests() {
super(EmailProvider.class, EmailContent.AUTHORITY);
@ -94,107 +76,10 @@ public class LegacyConversionsTests extends ProviderTestCase2<EmailProvider> {
* TODO: rainy day tests of all kinds
*/
/**
* Test basic conversion from Store message to Provider message
*
* TODO: Not a complete test of all fields, and some fields need special tests (e.g. flags)
* TODO: There are many special cases in the tested function, that need to be
* tested here as well.
*/
public void testUpdateMessageFields() throws MessagingException {
MimeMessage message = buildTestMessage(RECIPIENT_TO, RECIPIENT_CC, RECIPIENT_BCC,
REPLY_TO, SENDER, SUBJECT, null);
EmailContent.Message localMessage = new EmailContent.Message();
boolean result = LegacyConversions.updateMessageFields(localMessage, message, 1, 1);
assertTrue(result);
checkProviderMessage("testUpdateMessageFields", message, localMessage);
}
/**
* Test basic conversion from Store message to Provider message, when the provider message
* does not have a proper message-id.
*/
public void testUpdateMessageFieldsNoMessageId() throws MessagingException {
MimeMessage message = buildTestMessage(RECIPIENT_TO, RECIPIENT_CC, RECIPIENT_BCC,
REPLY_TO, SENDER, SUBJECT, null);
EmailContent.Message localMessage = new EmailContent.Message();
// If the source message-id is null, the target should be left as-is
localMessage.mMessageId = MESSAGE_ID_2;
message.removeHeader("Message-ID");
boolean result = LegacyConversions.updateMessageFields(localMessage, message, 1, 1);
assertTrue(result);
assertEquals(MESSAGE_ID_2, localMessage.mMessageId);
}
/**
* Build a lightweight Store message with simple field population
*/
private MimeMessage buildTestMessage(String to, String cc, String bcc, String replyTo,
String sender, String subject, String content) throws MessagingException {
MimeMessage message = new MimeMessage();
if (to != null) {
Address[] addresses = Address.parse(to);
message.setRecipients(RecipientType.TO, addresses);
}
if (cc != null) {
Address[] addresses = Address.parse(cc);
message.setRecipients(RecipientType.CC, addresses);
}
if (bcc != null) {
Address[] addresses = Address.parse(bcc);
message.setRecipients(RecipientType.BCC, addresses);
}
if (replyTo != null) {
Address[] addresses = Address.parse(replyTo);
message.setReplyTo(addresses);
}
if (sender != null) {
Address[] addresses = Address.parse(sender);
message.setFrom(addresses[0]);
}
if (subject != null) {
message.setSubject(subject);
}
if (content != null) {
TextBody body = new TextBody(content);
message.setBody(body);
}
message.setUid(UID);
message.setSentDate(new Date());
message.setInternalDate(new Date());
message.setMessageId(MESSAGE_ID);
return message;
}
/**
* Basic test of body parts conversion from Store message to Provider message.
* This tests that a null body part simply results in null text, and does not crash
* or return "null".
*
* TODO very incomplete, there are many permutations to be explored
*/
public void testUpdateBodyFieldsNullText() throws MessagingException {
EmailContent.Body localBody = new EmailContent.Body();
EmailContent.Message localMessage = new EmailContent.Message();
ArrayList<Part> viewables = new ArrayList<Part>();
Part emptyTextPart = new MimeBodyPart(null, "text/plain");
viewables.add(emptyTextPart);
// a "null" body part of type text/plain should result in a null mTextContent
final BodyFieldData data =
ConversionUtilities.parseBodyFields(viewables);
assertNull(data.textContent);
}
/**
* Sunny day test of adding attachments from an IMAP/POP message.
*/
public void testAddAttachments() throws MessagingException, IOException {
public void brokentestAddAttachments() throws MessagingException, IOException {
// Prepare a local message to add the attachments to
final long accountId = 1;
final long mailboxId = 1;
@ -251,7 +136,7 @@ public class LegacyConversionsTests extends ProviderTestCase2<EmailProvider> {
* @throws MessagingException
* @throws IOException
*/
public void testAttachmentDispositions() throws MessagingException, IOException {
public void brokentestAttachmentDispositions() throws MessagingException, IOException {
// Prepare a local message to add the attachments to
final long accountId = 1;
final long mailboxId = 1;
@ -301,7 +186,7 @@ public class LegacyConversionsTests extends ProviderTestCase2<EmailProvider> {
* Test that attachments aren't re-added in the DB. This supports the "partial download"
* nature of POP messages.
*/
public void testAddDuplicateAttachments() throws MessagingException, IOException {
public void brokentestAddDuplicateAttachments() throws MessagingException, IOException {
// Prepare a local message to add the attachments to
final long accountId = 1;
final long mailboxId = 1;
@ -393,24 +278,6 @@ public class LegacyConversionsTests extends ProviderTestCase2<EmailProvider> {
return legacyMessage;
}
/**
* Test the stringInequal helper
*/
public void testStringInequal() {
// Pairs that are "equal"
assertFalse(LegacyConversions.stringNotEqual(null, null));
assertFalse(LegacyConversions.stringNotEqual(null, ""));
assertFalse(LegacyConversions.stringNotEqual("", null));
assertFalse(LegacyConversions.stringNotEqual("", ""));
assertFalse(LegacyConversions.stringNotEqual("string-equal", "string-equal"));
// Pairs that are "inequal"
assertTrue(LegacyConversions.stringNotEqual(null, "string-inequal"));
assertTrue(LegacyConversions.stringNotEqual("", "string-inequal"));
assertTrue(LegacyConversions.stringNotEqual("string-inequal", null));
assertTrue(LegacyConversions.stringNotEqual("string-inequal", ""));
assertTrue(LegacyConversions.stringNotEqual("string-inequal-a", "string-inequal-b"));
}
/**
* Compare attachment that was converted from Part (expected) to Provider Attachment (actual)
*
@ -456,7 +323,7 @@ public class LegacyConversionsTests extends ProviderTestCase2<EmailProvider> {
/**
* Sunny day tests of converting an original message to a legacy message
*/
public void testMakeLegacyMessage() throws MessagingException {
public void brokentestMakeLegacyMessage() throws MessagingException {
// Set up and store a message in the provider
long account1Id = 1;
long mailbox1Id = 1;
@ -497,22 +364,6 @@ public class LegacyConversionsTests extends ProviderTestCase2<EmailProvider> {
checkLegacyMessage("forwarding", localMessage4, getMessage4);
}
/**
* Check equality of a pair of converted messages
*/
private void checkProviderMessage(String tag, Message expect, EmailContent.Message actual)
throws MessagingException {
assertEquals(tag, expect.getUid(), actual.mServerId);
assertEquals(tag, expect.getSubject(), actual.mSubject);
assertEquals(tag, Address.toHeader(expect.getFrom()), actual.mFrom);
assertEquals(tag, expect.getSentDate().getTime(), actual.mTimeStamp);
assertEquals(tag, Address.toHeader(expect.getRecipients(RecipientType.TO)), actual.mTo);
assertEquals(tag, Address.toHeader(expect.getRecipients(RecipientType.CC)), actual.mCc);
assertEquals(tag, expect.getMessageId(), actual.mMessageId);
assertEquals(tag, expect.isSet(Flag.SEEN), actual.mFlagRead);
assertEquals(tag, expect.isSet(Flag.FLAGGED), actual.mFlagFavorite);
}
/**
* Check equality of a pair of converted messages
*/

View File

@ -16,16 +16,16 @@
package com.android.emailcommon.internet;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.emailcommon.TempDirectory;
import com.android.emailcommon.mail.Address;
import com.android.emailcommon.mail.Flag;
import com.android.emailcommon.mail.Message.RecipientType;
import com.android.emailcommon.mail.MessagingException;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -270,7 +270,7 @@ public class MimeMessageTest extends AndroidTestCase {
/**
* Test for parsing address field.
*/
public void brokentestParsingAddressField() throws MessagingException {
public void testParsingAddressField() throws MessagingException {
MimeMessage message = new MimeMessage();
message.setHeader("From", "noname1@dom1.com");