mirror of https://github.com/M66B/FairEmail.git
Refactoring
This commit is contained in:
parent
a18767e9e8
commit
ed35dddceb
|
@ -40,7 +40,6 @@ import java.text.Normalizer;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
|
@ -51,7 +50,6 @@ import javax.mail.FolderClosedException;
|
|||
import javax.mail.Message;
|
||||
import javax.mail.MessageRemovedException;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.UIDFolder;
|
||||
import javax.mail.search.BodyTerm;
|
||||
import javax.mail.search.FlagTerm;
|
||||
|
@ -79,7 +77,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||
|
||||
private List<Long> messages = null;
|
||||
|
||||
private ConnectionHelper.ServiceHolder iservice = null;
|
||||
private MailService iservice = null;
|
||||
private IMAPFolder ifolder = null;
|
||||
private Message[] imessages = null;
|
||||
|
||||
|
@ -265,23 +263,11 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
|
|||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean debug = (prefs.getBoolean("debug", false) || BuildConfig.BETA_RELEASE);
|
||||
|
||||
String protocol = account.getProtocol();
|
||||
|
||||
// Get properties
|
||||
Properties props = MessageHelper.getSessionProperties(account.realm, account.insecure);
|
||||
if (!account.partial_fetch) {
|
||||
props.put("mail.imap.partialfetch", "false");
|
||||
props.put("mail.imaps.partialfetch", "false");
|
||||
}
|
||||
props.put("mail." + protocol + ".separatestoreconnection", "true");
|
||||
|
||||
// Create session
|
||||
Session isession = Session.getInstance(props, null);
|
||||
isession.setDebug(debug);
|
||||
|
||||
Log.i("Boundary server connecting account=" + account.name);
|
||||
iservice = new ConnectionHelper.ServiceHolder(protocol, isession);
|
||||
ConnectionHelper.connect(context, iservice, account);
|
||||
iservice = new MailService(context, account.getProtocol(), account.realm, account.insecure, debug);
|
||||
iservice.setPartialFetch(account.partial_fetch);
|
||||
iservice.setSeparateStoreConnection();
|
||||
iservice.connect(account);
|
||||
|
||||
Log.i("Boundary server opening folder=" + browsable.name);
|
||||
ifolder = (IMAPFolder) iservice.getStore().getFolder(browsable.name);
|
||||
|
|
|
@ -11,38 +11,22 @@ import android.os.Build;
|
|||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.bugsnag.android.BreadcrumbType;
|
||||
import com.bugsnag.android.Bugsnag;
|
||||
import com.sun.mail.imap.IMAPStore;
|
||||
import com.sun.mail.smtp.SMTPTransport;
|
||||
import com.sun.mail.util.MailConnectException;
|
||||
|
||||
import org.xbill.DNS.Lookup;
|
||||
import org.xbill.DNS.SimpleResolver;
|
||||
import org.xbill.DNS.Type;
|
||||
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.NoSuchProviderException;
|
||||
import javax.mail.Service;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
|
||||
public class ConnectionHelper {
|
||||
private static final String any4 = "0.0.0.0";
|
||||
// https://dns.watch/
|
||||
private static final String DEFAULT_DNS = "84.200.69.80";
|
||||
|
||||
|
@ -262,48 +246,6 @@ public class ConnectionHelper {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void connect(Context context, @NonNull ServiceHolder istore, EntityAccount account) throws MessagingException {
|
||||
connect(context, istore, account.host, account.port, account.user, account.password);
|
||||
}
|
||||
|
||||
static void connect(Context context, ServiceHolder iservice, EntityIdentity identity) throws MessagingException {
|
||||
connect(context, iservice, identity.host, identity.port, identity.user, identity.password);
|
||||
}
|
||||
|
||||
static void connect(Context context, ServiceHolder iservice, String host, int port, String user, String password) throws MessagingException {
|
||||
try {
|
||||
iservice.connect(context, host, port, user, password);
|
||||
} catch (MailConnectException ex) {
|
||||
if (!hasIPv6(host))
|
||||
throw ex;
|
||||
|
||||
try {
|
||||
Log.i("Binding to " + any4);
|
||||
iservice.getSession().getProperties().put("mail.imap.localaddress", any4);
|
||||
iservice.getSession().getProperties().put("mail.imaps.localaddress", any4);
|
||||
iservice.getSession().getProperties().put("mail.smtp.localaddress", any4);
|
||||
iservice.getSession().getProperties().put("mail.smtps.localaddress", any4);
|
||||
iservice.connect(context, host, port, user, password);
|
||||
} catch (Throwable ex1) {
|
||||
Log.w(ex1);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasIPv6(String host) {
|
||||
boolean has = false;
|
||||
try {
|
||||
for (InetAddress iaddr : InetAddress.getAllByName(host)) {
|
||||
Log.i(host + " resolves to " + iaddr);
|
||||
if (iaddr instanceof Inet6Address)
|
||||
has = true;
|
||||
}
|
||||
} catch (UnknownHostException ignored) {
|
||||
}
|
||||
return has;
|
||||
}
|
||||
|
||||
static boolean airplaneMode(Context context) {
|
||||
return Settings.System.getInt(context.getContentResolver(),
|
||||
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
|
||||
|
@ -374,66 +316,4 @@ public class ConnectionHelper {
|
|||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static class ServiceHolder implements AutoCloseable {
|
||||
private String protocol;
|
||||
private Session issesion;
|
||||
private Service iservice;
|
||||
|
||||
private ServiceHolder() {
|
||||
}
|
||||
|
||||
ServiceHolder(String protocol, Session issesion) {
|
||||
this.protocol = protocol;
|
||||
this.issesion = issesion;
|
||||
}
|
||||
|
||||
void connect(Context context, String host, int port, String user, String password) throws MessagingException {
|
||||
if ("imap".equals(protocol) || "imaps".equals(protocol)) {
|
||||
iservice = issesion.getStore(protocol);
|
||||
iservice.connect(host, port, user, password);
|
||||
|
||||
// https://www.ietf.org/rfc/rfc2971.txt
|
||||
if (getStore().hasCapability("ID"))
|
||||
try {
|
||||
Map<String, String> id = new LinkedHashMap<>();
|
||||
id.put("name", context.getString(R.string.app_name));
|
||||
id.put("version", BuildConfig.VERSION_NAME);
|
||||
Map<String, String> sid = getStore().id(id);
|
||||
if (sid != null) {
|
||||
Map<String, String> crumb = new HashMap<>();
|
||||
for (String key : sid.keySet()) {
|
||||
crumb.put(key, sid.get(key));
|
||||
EntityLog.log(context, "Server " + key + "=" + sid.get(key));
|
||||
}
|
||||
Bugsnag.leaveBreadcrumb("server", BreadcrumbType.LOG, crumb);
|
||||
}
|
||||
} catch (MessagingException ex) {
|
||||
Log.w(ex);
|
||||
}
|
||||
|
||||
} else if ("smtp".equals(protocol) || "smtps".equals(protocol)) {
|
||||
iservice = issesion.getTransport(protocol);
|
||||
iservice.connect(host, port, user, password);
|
||||
} else
|
||||
throw new NoSuchProviderException(protocol);
|
||||
}
|
||||
|
||||
Session getSession() {
|
||||
return this.issesion;
|
||||
}
|
||||
|
||||
IMAPStore getStore() {
|
||||
return (IMAPStore) this.iservice;
|
||||
}
|
||||
|
||||
SMTPTransport getTransport() {
|
||||
return (SMTPTransport) this.iservice;
|
||||
}
|
||||
|
||||
public void close() throws MessagingException {
|
||||
if (iservice != null)
|
||||
iservice.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
@ -126,7 +127,7 @@ class Core {
|
|||
static void processOperations(
|
||||
Context context,
|
||||
EntityAccount account, EntityFolder folder,
|
||||
Session isession, Store istore, Folder ifolder,
|
||||
Store istore, Folder ifolder,
|
||||
State state)
|
||||
throws MessagingException, JSONException, IOException {
|
||||
try {
|
||||
|
@ -209,15 +210,15 @@ class Core {
|
|||
" msg=" + op.message +
|
||||
" args=" + op.args);
|
||||
else
|
||||
onAdd(context, jargs, folder, message, isession, (IMAPStore) istore, (IMAPFolder) ifolder);
|
||||
onAdd(context, jargs, folder, message, (IMAPStore) istore, (IMAPFolder) ifolder);
|
||||
break;
|
||||
|
||||
case EntityOperation.MOVE:
|
||||
onMove(context, jargs, false, folder, message, isession, (IMAPStore) istore, (IMAPFolder) ifolder);
|
||||
onMove(context, jargs, false, folder, message, (IMAPStore) istore, (IMAPFolder) ifolder);
|
||||
break;
|
||||
|
||||
case EntityOperation.COPY:
|
||||
onMove(context, jargs, true, folder, message, isession, (IMAPStore) istore, (IMAPFolder) ifolder);
|
||||
onMove(context, jargs, true, folder, message, (IMAPStore) istore, (IMAPFolder) ifolder);
|
||||
break;
|
||||
|
||||
case EntityOperation.DELETE:
|
||||
|
@ -460,7 +461,7 @@ class Core {
|
|||
}
|
||||
}
|
||||
|
||||
private static void onAdd(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, Session isession, IMAPStore istore, IMAPFolder ifolder) throws MessagingException, JSONException, IOException {
|
||||
private static void onAdd(Context context, JSONArray jargs, EntityFolder folder, EntityMessage message, IMAPStore istore, IMAPFolder ifolder) throws MessagingException, JSONException, IOException {
|
||||
// Add message
|
||||
DB db = DB.getInstance(context);
|
||||
|
||||
|
@ -483,6 +484,9 @@ class Core {
|
|||
db.message().setMessageMsgId(message.id, message.msgid);
|
||||
}
|
||||
|
||||
Properties props = MessageHelper.getSessionProperties(null, false);
|
||||
Session isession = Session.getInstance(props, null);
|
||||
|
||||
// Get raw message
|
||||
MimeMessage imessage;
|
||||
if (folder.id.equals(message.folder)) {
|
||||
|
@ -577,7 +581,7 @@ class Core {
|
|||
}
|
||||
}
|
||||
|
||||
private static void onMove(Context context, JSONArray jargs, boolean copy, EntityFolder folder, EntityMessage message, Session isession, IMAPStore istore, IMAPFolder ifolder) throws JSONException, MessagingException, IOException {
|
||||
private static void onMove(Context context, JSONArray jargs, boolean copy, EntityFolder folder, EntityMessage message, IMAPStore istore, IMAPFolder ifolder) throws JSONException, MessagingException, IOException {
|
||||
// Move message
|
||||
DB db = DB.getInstance(context);
|
||||
|
||||
|
@ -604,6 +608,9 @@ class Core {
|
|||
imessage.writeTo(os);
|
||||
}
|
||||
|
||||
Properties props = MessageHelper.getSessionProperties(null, false);
|
||||
Session isession = Session.getInstance(props, null);
|
||||
|
||||
Message icopy;
|
||||
try (InputStream is = new BufferedInputStream(new FileInputStream(file))) {
|
||||
icopy = new MimeMessage(isession, is);
|
||||
|
|
|
@ -67,10 +67,8 @@ import java.util.Collections;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Folder;
|
||||
import javax.mail.Session;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE;
|
||||
|
@ -531,12 +529,9 @@ public class FragmentAccount extends FragmentBase {
|
|||
result.folders = new ArrayList<>();
|
||||
|
||||
// Check IMAP server / get folders
|
||||
Properties props = MessageHelper.getSessionProperties(realm, insecure);
|
||||
Session isession = Session.getInstance(props, null);
|
||||
isession.setDebug(true);
|
||||
try (ConnectionHelper.ServiceHolder iservice =
|
||||
new ConnectionHelper.ServiceHolder("imap" + (starttls ? "" : "s"), isession)) {
|
||||
ConnectionHelper.connect(context, iservice, host, Integer.parseInt(port), user, password);
|
||||
String protocol = "imap" + (starttls ? "" : "s");
|
||||
try (MailService iservice = new MailService(context, protocol, realm, insecure, true)) {
|
||||
iservice.connect(host, Integer.parseInt(port), user, password);
|
||||
|
||||
result.idle = iservice.getStore().hasCapability("IDLE");
|
||||
|
||||
|
@ -888,13 +883,9 @@ public class FragmentAccount extends FragmentBase {
|
|||
// Check IMAP server
|
||||
EntityFolder inbox = null;
|
||||
if (check) {
|
||||
Properties props = MessageHelper.getSessionProperties(realm, insecure);
|
||||
Session isession = Session.getInstance(props, null);
|
||||
isession.setDebug(true);
|
||||
|
||||
try (ConnectionHelper.ServiceHolder iservice
|
||||
= new ConnectionHelper.ServiceHolder("imap" + (starttls ? "" : "s"), isession)) {
|
||||
ConnectionHelper.connect(context, iservice, host, Integer.parseInt(port), user, password);
|
||||
String protocol = "imap" + (starttls ? "" : "s");
|
||||
try (MailService iservice = new MailService(context, protocol, realm, insecure, true)) {
|
||||
iservice.connect(host, Integer.parseInt(port), user, password);
|
||||
|
||||
for (Folder ifolder : iservice.getStore().getDefaultFolder().list("*")) {
|
||||
// Check folder attributes
|
||||
|
|
|
@ -64,16 +64,10 @@ import androidx.lifecycle.Lifecycle;
|
|||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Session;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE;
|
||||
|
@ -678,32 +672,11 @@ public class FragmentIdentity extends FragmentBase {
|
|||
|
||||
// Check SMTP server
|
||||
if (check) {
|
||||
String protocol = (starttls ? "smtp" : "smtps");
|
||||
|
||||
// Get properties
|
||||
Properties props = MessageHelper.getSessionProperties(realm, insecure);
|
||||
|
||||
String haddr;
|
||||
if (use_ip) {
|
||||
InetAddress addr = InetAddress.getByName(host);
|
||||
if (addr instanceof Inet4Address)
|
||||
haddr = "[" + Inet4Address.getLocalHost().getHostAddress() + "]";
|
||||
else
|
||||
haddr = "[IPv6:" + Inet6Address.getLocalHost().getHostAddress() + "]";
|
||||
} else
|
||||
haddr = host;
|
||||
|
||||
Log.i("Send localhost=" + haddr);
|
||||
props.put("mail." + protocol + ".localhost", haddr);
|
||||
|
||||
// Create session
|
||||
Session isession = Session.getInstance(props, null);
|
||||
isession.setDebug(true);
|
||||
|
||||
// Create transport
|
||||
try (ConnectionHelper.ServiceHolder iservice =
|
||||
new ConnectionHelper.ServiceHolder(protocol, isession)) {
|
||||
ConnectionHelper.connect(context, iservice, host, Integer.parseInt(port), user, password);
|
||||
String protocol = (starttls ? "smtp" : "smtps");
|
||||
try (MailService iservice = new MailService(context, protocol, realm, insecure, true)) {
|
||||
iservice.setUseIp(use_ip, host);
|
||||
iservice.connect(host, Integer.parseInt(port), user, password);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,10 +57,8 @@ import java.net.UnknownHostException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Folder;
|
||||
import javax.mail.Session;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
|
@ -251,12 +249,9 @@ public class FragmentQuickSetup extends FragmentBase {
|
|||
long now = new Date().getTime();
|
||||
|
||||
{
|
||||
Properties props = MessageHelper.getSessionProperties(null, false);
|
||||
Session isession = Session.getInstance(props, null);
|
||||
isession.setDebug(true);
|
||||
try (ConnectionHelper.ServiceHolder iservice =
|
||||
new ConnectionHelper.ServiceHolder(provider.imap_starttls ? "imap" : "imaps", isession)) {
|
||||
ConnectionHelper.connect(context, iservice, provider.imap_host, provider.imap_port, user, password);
|
||||
String protocol = provider.imap_starttls ? "imap" : "imaps";
|
||||
try (MailService iservice = new MailService(context, protocol, null, false, true)) {
|
||||
iservice.connect(provider.imap_host, provider.imap_port, user, password);
|
||||
|
||||
boolean inbox = false;
|
||||
boolean drafts = false;
|
||||
|
@ -316,12 +311,9 @@ public class FragmentQuickSetup extends FragmentBase {
|
|||
}
|
||||
|
||||
{
|
||||
Properties props = MessageHelper.getSessionProperties(null, false);
|
||||
Session isession = Session.getInstance(props, null);
|
||||
isession.setDebug(true);
|
||||
try (ConnectionHelper.ServiceHolder iservice
|
||||
= new ConnectionHelper.ServiceHolder(provider.smtp_starttls ? "smtp" : "smtps", isession)) {
|
||||
ConnectionHelper.connect(context, iservice, provider.smtp_host, provider.smtp_port, user, password);
|
||||
String protocol = provider.smtp_starttls ? "smtp" : "smtps";
|
||||
try (MailService iservice = new MailService(context, protocol, null, false, true)) {
|
||||
iservice.connect(provider.smtp_host, provider.smtp_port, user, password);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
package eu.faircode.email;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.bugsnag.android.BreadcrumbType;
|
||||
import com.bugsnag.android.Bugsnag;
|
||||
import com.sun.mail.imap.IMAPStore;
|
||||
import com.sun.mail.smtp.SMTPTransport;
|
||||
import com.sun.mail.util.MailConnectException;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.NoSuchProviderException;
|
||||
import javax.mail.Service;
|
||||
import javax.mail.Session;
|
||||
|
||||
public class MailService implements AutoCloseable {
|
||||
private Context context;
|
||||
private String protocol;
|
||||
private boolean debug;
|
||||
private Properties properties;
|
||||
private Session isession;
|
||||
private Service iservice;
|
||||
|
||||
private static final String any4 = "0.0.0.0";
|
||||
|
||||
private MailService() {
|
||||
}
|
||||
|
||||
MailService(Context context, String protocol, String realm, boolean insecure, boolean debug) {
|
||||
this.context = context;
|
||||
this.protocol = protocol;
|
||||
this.debug = debug;
|
||||
this.properties = MessageHelper.getSessionProperties(realm, insecure);
|
||||
}
|
||||
|
||||
void setPartialFetch(boolean enabled) {
|
||||
if (!enabled)
|
||||
this.properties.put("mail." + this.protocol + ".partialfetch", "false");
|
||||
}
|
||||
|
||||
void setUseIp(boolean enabled, String host) throws UnknownHostException {
|
||||
String haddr;
|
||||
if (enabled) {
|
||||
InetAddress addr = InetAddress.getByName(host);
|
||||
if (addr instanceof Inet4Address)
|
||||
haddr = "[" + Inet4Address.getLocalHost().getHostAddress() + "]";
|
||||
else
|
||||
haddr = "[IPv6:" + Inet6Address.getLocalHost().getHostAddress() + "]";
|
||||
} else
|
||||
haddr = host;
|
||||
|
||||
Log.i("Send localhost=" + haddr);
|
||||
this.properties.put("mail." + this.protocol + ".localhost", haddr);
|
||||
}
|
||||
|
||||
void setSeparateStoreConnection() {
|
||||
this.properties.put("mail." + this.protocol + ".separatestoreconnection", "true");
|
||||
}
|
||||
|
||||
public void connect(EntityAccount account) throws MessagingException {
|
||||
connect(account.host, account.port, account.user, account.password);
|
||||
}
|
||||
|
||||
public void connect(EntityIdentity identity) throws MessagingException {
|
||||
connect(identity.host, identity.port, identity.user, identity.password);
|
||||
}
|
||||
|
||||
public void connect(String host, int port, String user, String password) throws MessagingException {
|
||||
try {
|
||||
_connect(context, host, port, user, password);
|
||||
} catch (MailConnectException ex) {
|
||||
if (!hasIPv6(host))
|
||||
throw ex;
|
||||
|
||||
try {
|
||||
Log.i("Binding to " + any4);
|
||||
properties.put("mail.imap.localaddress", any4);
|
||||
properties.put("mail.imaps.localaddress", any4);
|
||||
properties.put("mail.smtp.localaddress", any4);
|
||||
properties.put("mail.smtps.localaddress", any4);
|
||||
_connect(context, host, port, user, password);
|
||||
} catch (Throwable ex1) {
|
||||
Log.w(ex1);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void _connect(Context context, String host, int port, String user, String password) throws MessagingException {
|
||||
isession = Session.getInstance(properties, null);
|
||||
isession.setDebug(debug);
|
||||
//System.setProperty("mail.socket.debug", Boolean.toString(debug));
|
||||
|
||||
if ("imap".equals(protocol) || "imaps".equals(protocol)) {
|
||||
iservice = isession.getStore(protocol);
|
||||
iservice.connect(host, port, user, password);
|
||||
|
||||
// https://www.ietf.org/rfc/rfc2971.txt
|
||||
if (getStore().hasCapability("ID"))
|
||||
try {
|
||||
Map<String, String> id = new LinkedHashMap<>();
|
||||
id.put("name", context.getString(R.string.app_name));
|
||||
id.put("version", BuildConfig.VERSION_NAME);
|
||||
Map<String, String> sid = getStore().id(id);
|
||||
if (sid != null) {
|
||||
Map<String, String> crumb = new HashMap<>();
|
||||
for (String key : sid.keySet()) {
|
||||
crumb.put(key, sid.get(key));
|
||||
EntityLog.log(context, "Server " + key + "=" + sid.get(key));
|
||||
}
|
||||
Bugsnag.leaveBreadcrumb("server", BreadcrumbType.LOG, crumb);
|
||||
}
|
||||
} catch (MessagingException ex) {
|
||||
Log.w(ex);
|
||||
}
|
||||
|
||||
} else if ("smtp".equals(protocol) || "smtps".equals(protocol)) {
|
||||
iservice = isession.getTransport(protocol);
|
||||
iservice.connect(host, port, user, password);
|
||||
} else
|
||||
throw new NoSuchProviderException(protocol);
|
||||
}
|
||||
|
||||
private static boolean hasIPv6(String host) {
|
||||
boolean has = false;
|
||||
try {
|
||||
for (InetAddress iaddr : InetAddress.getAllByName(host)) {
|
||||
Log.i(host + " resolves to " + iaddr);
|
||||
if (iaddr instanceof Inet6Address)
|
||||
has = true;
|
||||
}
|
||||
} catch (UnknownHostException ignored) {
|
||||
}
|
||||
return has;
|
||||
}
|
||||
|
||||
IMAPStore getStore() {
|
||||
return (IMAPStore) this.iservice;
|
||||
}
|
||||
|
||||
SMTPTransport getTransport() {
|
||||
return (SMTPTransport) this.iservice;
|
||||
}
|
||||
|
||||
public void close() throws MessagingException {
|
||||
try {
|
||||
if (iservice != null)
|
||||
iservice.close();
|
||||
} finally {
|
||||
this.context = null;
|
||||
this.properties = null;
|
||||
this.isession = null;
|
||||
this.iservice = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,9 +38,6 @@ import androidx.preference.PreferenceManager;
|
|||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
@ -312,32 +309,9 @@ public class ServiceSend extends ServiceBase {
|
|||
if (ident == null)
|
||||
throw new IllegalArgumentException("Identity not found");
|
||||
|
||||
String protocol = ident.getProtocol();
|
||||
|
||||
// Get properties
|
||||
Properties props = MessageHelper.getSessionProperties(ident.realm, ident.insecure);
|
||||
|
||||
String haddr;
|
||||
if (ident.use_ip) {
|
||||
InetAddress addr = InetAddress.getByName(ident.host);
|
||||
if (addr instanceof Inet4Address)
|
||||
haddr = "[" + Inet4Address.getLocalHost().getHostAddress() + "]";
|
||||
else {
|
||||
// Inet6Address.getLocalHost() will return the IPv6 local host
|
||||
byte[] LOOPBACK = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
|
||||
haddr = "[IPv6:" + Inet6Address.getByAddress("ip6-localhost", LOOPBACK, 0).getHostAddress() + "]";
|
||||
}
|
||||
} else
|
||||
haddr = ident.host;
|
||||
|
||||
EntityLog.log(this, "Send localhost=" + haddr);
|
||||
props.put("mail." + protocol + ".localhost", haddr);
|
||||
|
||||
// Create session
|
||||
final Session isession = Session.getInstance(props, null);
|
||||
isession.setDebug(debug);
|
||||
|
||||
// Create message
|
||||
Properties props = MessageHelper.getSessionProperties(null, false);
|
||||
Session isession = Session.getInstance(props, null);
|
||||
MimeMessage imessage = MessageHelper.from(this, message, ident, isession);
|
||||
|
||||
// Add reply to
|
||||
|
@ -365,10 +339,13 @@ public class ServiceSend extends ServiceBase {
|
|||
}
|
||||
|
||||
// Create transport
|
||||
try (ConnectionHelper.ServiceHolder iservice = new ConnectionHelper.ServiceHolder(protocol, isession)) {
|
||||
try (MailService iservice = new MailService(
|
||||
this, ident.getProtocol(), ident.realm, ident.insecure, debug)) {
|
||||
iservice.setUseIp(ident.use_ip, ident.host);
|
||||
|
||||
// Connect transport
|
||||
db.identity().setIdentityState(ident.id, "connecting");
|
||||
ConnectionHelper.connect(this, iservice, ident);
|
||||
iservice.connect(ident);
|
||||
db.identity().setIdentityState(ident.id, "connected");
|
||||
|
||||
// Send message
|
||||
|
|
|
@ -58,7 +58,6 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
@ -74,7 +73,6 @@ import javax.mail.MessageRemovedException;
|
|||
import javax.mail.MessagingException;
|
||||
import javax.mail.NoSuchProviderException;
|
||||
import javax.mail.ReadOnlyFolderException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.StoreClosedException;
|
||||
import javax.mail.UIDFolder;
|
||||
import javax.mail.event.ConnectionAdapter;
|
||||
|
@ -610,22 +608,10 @@ public class ServiceSynchronize extends ServiceBase {
|
|||
// Debug
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
boolean debug = (prefs.getBoolean("debug", false) || BuildConfig.DEBUG);
|
||||
//System.setProperty("mail.socket.debug", Boolean.toString(debug));
|
||||
|
||||
// Get properties
|
||||
Properties props = MessageHelper.getSessionProperties(account.realm, account.insecure);
|
||||
if (!account.partial_fetch) {
|
||||
props.put("mail.imap.partialfetch", "false");
|
||||
props.put("mail.imaps.partialfetch", "false");
|
||||
}
|
||||
|
||||
// Create session
|
||||
final Session isession = Session.getInstance(props, null);
|
||||
isession.setDebug(debug);
|
||||
// adb -t 1 logcat | grep "fairemail\|System.out"
|
||||
|
||||
final ConnectionHelper.ServiceHolder iservice =
|
||||
new ConnectionHelper.ServiceHolder(account.getProtocol(), isession);
|
||||
final MailService iservice = new MailService(
|
||||
this, account.getProtocol(), account.realm, account.insecure, debug);
|
||||
iservice.setPartialFetch(account.partial_fetch);
|
||||
|
||||
final Map<EntityFolder, IMAPFolder> mapFolders = new HashMap<>();
|
||||
List<Thread> idlers = new ArrayList<>();
|
||||
|
@ -636,7 +622,7 @@ public class ServiceSynchronize extends ServiceBase {
|
|||
db.account().setAccountState(account.id, "connecting");
|
||||
|
||||
try {
|
||||
ConnectionHelper.connect(this, iservice, account);
|
||||
iservice.connect(account);
|
||||
} catch (Throwable ex) {
|
||||
if (ex instanceof AuthenticationFailedException) {
|
||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
@ -1089,7 +1075,7 @@ public class ServiceSynchronize extends ServiceBase {
|
|||
|
||||
Core.processOperations(ServiceSynchronize.this,
|
||||
account, folder,
|
||||
isession, iservice.getStore(), ifolder,
|
||||
iservice.getStore(), ifolder,
|
||||
state);
|
||||
|
||||
} catch (Throwable ex) {
|
||||
|
|
Loading…
Reference in New Issue