diff --git a/src/com/fsck/k9/mail/ServerSettings.java b/src/com/fsck/k9/mail/ServerSettings.java index cb36459c6..ef237e0a4 100644 --- a/src/com/fsck/k9/mail/ServerSettings.java +++ b/src/com/fsck/k9/mail/ServerSettings.java @@ -29,6 +29,8 @@ public class ServerSettings { /** * The port number of the server. + * + * {@code -1} if not applicable for the store or transport. */ public final int port; @@ -91,6 +93,24 @@ public class ServerSettings { this.password = password; } + /** + * Creates an "empty" {@code ServerSettings} object. + * + * Everything but {@link ServerSettings#type} is unused. + * + * @param type + * see {@link ServerSettings#type} + */ + public ServerSettings(String type) { + this.type = type; + host = null; + port = -1; + connectionSecurity = ConnectionSecurity.NONE; + authenticationType = null; + username = null; + password = null; + } + /** * Returns store- or transport-specific settings as key/value pair. * diff --git a/src/com/fsck/k9/mail/Transport.java b/src/com/fsck/k9/mail/Transport.java index 04634f01e..cd99923e5 100644 --- a/src/com/fsck/k9/mail/Transport.java +++ b/src/com/fsck/k9/mail/Transport.java @@ -22,6 +22,29 @@ public abstract class Transport { } } + /** + * Decodes the contents of transport-specific URIs and puts them into a {@link ServerSettings} + * object. + * + * @param uri + * the transport-specific URI to decode + * + * @return A {@link ServerSettings} object holding the settings contained in the URI. + * + * @see SmtpTransport#decodeUri(String) + * @see WebDavTransport#decodeUri(String) + */ + public static ServerSettings decodeTransportUri(String uri) { + if (uri.startsWith("smtp")) { + return SmtpTransport.decodeUri(uri); + } else if (uri.startsWith("webdav")) { + return WebDavTransport.decodeUri(uri); + } else { + throw new IllegalArgumentException("Not a valid transport URI"); + } + } + + public abstract void open() throws MessagingException; public abstract void sendMessage(Message message) throws MessagingException; diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index 552c883fc..160abd2a3 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -31,95 +31,134 @@ import org.apache.commons.codec.binary.Hex; import java.util.*; public class SmtpTransport extends Transport { + private static final String TRANSPORT_TYPE = "SMTP"; + public static final int CONNECTION_SECURITY_NONE = 0; - public static final int CONNECTION_SECURITY_TLS_OPTIONAL = 1; - public static final int CONNECTION_SECURITY_TLS_REQUIRED = 2; - public static final int CONNECTION_SECURITY_SSL_REQUIRED = 3; - public static final int CONNECTION_SECURITY_SSL_OPTIONAL = 4; - String mHost; - - int mPort; - - String mUsername; - - String mPassword; - - String mAuthType; - - int mConnectionSecurity; - - boolean mSecure; - - Socket mSocket; - - PeekableInputStream mIn; - - OutputStream mOut; - private boolean m8bitEncodingAllowed; /** + * Decodes a SmtpTransport URI. + * + *
Possible forms:
+ ** smtp://user:password@server:port CONNECTION_SECURITY_NONE * smtp+tls://user:password@server:port CONNECTION_SECURITY_TLS_OPTIONAL * smtp+tls+://user:password@server:port CONNECTION_SECURITY_TLS_REQUIRED * smtp+ssl+://user:password@server:port CONNECTION_SECURITY_SSL_REQUIRED * smtp+ssl://user:password@server:port CONNECTION_SECURITY_SSL_OPTIONAL - * - * @param _uri + **/ - public SmtpTransport(String _uri) throws MessagingException { - URI uri; + public static ServerSettings decodeUri(String uri) { + String host; + int port; + ConnectionSecurity connectionSecurity; + String authenticationType = null; + String username = null; + String password = null; + + URI smtpUri; try { - uri = new URI(_uri); + smtpUri = new URI(uri); } catch (URISyntaxException use) { - throw new MessagingException("Invalid SmtpTransport URI", use); + throw new IllegalArgumentException("Invalid SmtpTransport URI", use); } - String scheme = uri.getScheme(); + String scheme = smtpUri.getScheme(); if (scheme.equals("smtp")) { - mConnectionSecurity = CONNECTION_SECURITY_NONE; - mPort = 25; + connectionSecurity = ConnectionSecurity.NONE; + port = 25; } else if (scheme.equals("smtp+tls")) { - mConnectionSecurity = CONNECTION_SECURITY_TLS_OPTIONAL; - mPort = 25; + connectionSecurity = ConnectionSecurity.STARTTLS_OPTIONAL; + port = 25; } else if (scheme.equals("smtp+tls+")) { - mConnectionSecurity = CONNECTION_SECURITY_TLS_REQUIRED; - mPort = 25; + connectionSecurity = ConnectionSecurity.STARTTLS_REQUIRED; + port = 25; } else if (scheme.equals("smtp+ssl+")) { - mConnectionSecurity = CONNECTION_SECURITY_SSL_REQUIRED; - mPort = 465; + connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED; + port = 465; } else if (scheme.equals("smtp+ssl")) { - mConnectionSecurity = CONNECTION_SECURITY_SSL_OPTIONAL; - mPort = 465; + connectionSecurity = ConnectionSecurity.SSL_TLS_OPTIONAL; + port = 465; } else { - throw new MessagingException("Unsupported protocol"); + throw new IllegalArgumentException("Unsupported protocol (" + scheme + ")"); } - mHost = uri.getHost(); + host = smtpUri.getHost(); - if (uri.getPort() != -1) { - mPort = uri.getPort(); + if (smtpUri.getPort() != -1) { + port = smtpUri.getPort(); } - if (uri.getUserInfo() != null) { + if (smtpUri.getUserInfo() != null) { try { - String[] userInfoParts = uri.getUserInfo().split(":"); - mUsername = URLDecoder.decode(userInfoParts[0], "UTF-8"); + String[] userInfoParts = smtpUri.getUserInfo().split(":"); + username = URLDecoder.decode(userInfoParts[0], "UTF-8"); if (userInfoParts.length > 1) { - mPassword = URLDecoder.decode(userInfoParts[1], "UTF-8"); + password = URLDecoder.decode(userInfoParts[1], "UTF-8"); } if (userInfoParts.length > 2) { - mAuthType = userInfoParts[2]; + authenticationType = userInfoParts[2]; } } catch (UnsupportedEncodingException enc) { // This shouldn't happen since the encoding is hardcoded to UTF-8 - Log.e(K9.LOG_TAG, "Couldn't urldecode username or password.", enc); + throw new IllegalArgumentException("Couldn't urldecode username or password.", enc); } } + + return new ServerSettings(TRANSPORT_TYPE, host, port, connectionSecurity, + authenticationType, username, password); + } + + + String mHost; + int mPort; + String mUsername; + String mPassword; + String mAuthType; + int mConnectionSecurity; + boolean mSecure; + Socket mSocket; + PeekableInputStream mIn; + OutputStream mOut; + private boolean m8bitEncodingAllowed; + + + public SmtpTransport(String uri) throws MessagingException { + ServerSettings settings; + try { + settings = decodeUri(uri); + } catch (IllegalArgumentException e) { + throw new MessagingException("Error while decoding transport URI", e); + } + + mHost = settings.host; + mPort = settings.port; + + switch (settings.connectionSecurity) { + case NONE: + mConnectionSecurity = CONNECTION_SECURITY_NONE; + break; + case STARTTLS_OPTIONAL: + mConnectionSecurity = CONNECTION_SECURITY_TLS_OPTIONAL; + break; + case STARTTLS_REQUIRED: + mConnectionSecurity = CONNECTION_SECURITY_TLS_REQUIRED; + break; + case SSL_TLS_OPTIONAL: + mConnectionSecurity = CONNECTION_SECURITY_SSL_OPTIONAL; + break; + case SSL_TLS_REQUIRED: + mConnectionSecurity = CONNECTION_SECURITY_SSL_REQUIRED; + break; + } + + mAuthType = settings.authenticationType; + mUsername = settings.username; + mPassword = settings.password; } @Override diff --git a/src/com/fsck/k9/mail/transport/WebDavTransport.java b/src/com/fsck/k9/mail/transport/WebDavTransport.java index 72159a5e6..7fd151e70 100644 --- a/src/com/fsck/k9/mail/transport/WebDavTransport.java +++ b/src/com/fsck/k9/mail/transport/WebDavTransport.java @@ -7,10 +7,26 @@ import com.fsck.k9.Account; import com.fsck.k9.K9; import com.fsck.k9.mail.Message; import com.fsck.k9.mail.MessagingException; +import com.fsck.k9.mail.ServerSettings; import com.fsck.k9.mail.Transport; import com.fsck.k9.mail.store.WebDavStore; public class WebDavTransport extends Transport { + private static final String TRANSPORT_TYPE = "WebDAV"; + + /** + * Decodes a WebDavTransport URI. + * + *
+ * Note: Right now there is nothing to decode. Everything related to sending messages + * via WebDAV is handled by {@link WebDavStore}. + *
+ */ + public static ServerSettings decodeUri(String uri) { + return new ServerSettings(TRANSPORT_TYPE); + } + + private WebDavStore store; public WebDavTransport(Account account) throws MessagingException {