Decode transport URIs into ServerSettings objects

This commit is contained in:
cketti 2011-06-07 16:39:41 +02:00
parent bccf0b5546
commit 4a807e33d9
4 changed files with 149 additions and 51 deletions

View File

@ -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.
*

View File

@ -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;

View File

@ -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.
*
* <p>Possible forms:</p>
* <pre>
* 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
* </pre>
*/
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

View File

@ -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.
*
* <p>
* <b>Note:</b> Right now there is nothing to decode. Everything related to sending messages
* via WebDAV is handled by {@link WebDavStore}.
* </p>
*/
public static ServerSettings decodeUri(String uri) {
return new ServerSettings(TRANSPORT_TYPE);
}
private WebDavStore store;
public WebDavTransport(Account account) throws MessagingException {