📄 imapstore.java
字号:
// check if STARTTLS is enabled
s = session.getProperty("mail." + name + ".starttls.enable");
if (s != null && s.equalsIgnoreCase("true")) {
if (debug)
out.println("DEBUG: enable STARTTLS");
enableStartTLS = true;
}
// check if SASL is enabled
s = session.getProperty("mail." + name + ".sasl.enable");
if (s != null && s.equalsIgnoreCase("true")) {
if (debug)
out.println("DEBUG: enable SASL");
enableSASL = true;
}
// check if SASL mechanisms are specified
if (enableSASL) {
s = session.getProperty("mail." + name + ".sasl.mechanisms");
if (s != null && s.length() > 0) {
if (debug)
out.println("DEBUG: SASL mechanisms allowed: " + s);
Vector v = new Vector(5);
StringTokenizer st = new StringTokenizer(s, " ,");
while (st.hasMoreTokens()) {
String m = st.nextToken();
if (m.length() > 0)
v.addElement(m);
}
saslMechanisms = new String[v.size()];
v.copyInto(saslMechanisms);
}
}
// check if an authorization ID has been specified
s = session.getProperty("mail." + name + ".sasl.authorizationid");
if (s != null) {
authorizationID = s;
if (debug)
out.println("DEBUG: mail.imap.sasl.authorizationid: " +
authorizationID);
}
// check if a SASL realm has been specified
s = session.getProperty("mail." + name + ".sasl.realm");
if (s != null) {
saslRealm = s;
if (debug)
out.println("DEBUG: mail.imap.sasl.realm: " + saslRealm);
}
// check if forcePasswordRefresh is enabled
s = session.getProperty("mail." + name + ".forcepasswordrefresh");
if (s != null && s.equalsIgnoreCase("true")) {
if (debug)
out.println("DEBUG: enable forcePasswordRefresh");
forcePasswordRefresh = true;
}
// check if enableimapevents is enabled
s = session.getProperty("mail." + name + ".enableimapevents");
if (s != null && s.equalsIgnoreCase("true")) {
if (debug)
out.println("DEBUG: enable IMAP events");
enableImapEvents = true;
}
}
/**
* Implementation of protocolConnect(). Will create a connection
* to the server and authenticate the user using the mechanisms
* specified by various properties. <p>
*
* The <code>host</code>, <code>user</code>, and <code>password</code>
* parameters must all be non-null. If the authentication mechanism
* being used does not require a password, an empty string or other
* suitable dummy password should be used.
*/
protected synchronized boolean
protocolConnect(String host, int pport, String user, String password)
throws MessagingException {
IMAPProtocol protocol = null;
// check for non-null values of host, password, user
if (host == null || password == null || user == null) {
if (debug)
out.println("DEBUG: protocolConnect returning false" +
", host=" + host +
", user=" + user +
", password=" + (password != null ?
"<non-null>" : "<null>"));
return false;
}
// set the port correctly
if (pport != -1) {
port = pport;
} else {
String portstring = session.getProperty("mail."+name+".port");
if (portstring != null) {
port = Integer.parseInt(portstring);
}
}
// use the default if needed
if (port == -1) {
port = defaultPort;
}
try {
boolean poolEmpty;
synchronized (pool) {
poolEmpty = pool.authenticatedConnections.isEmpty();
}
if (poolEmpty) {
protocol = new IMAPProtocol(name, host, port,
session.getDebug(),
session.getDebugOut(),
session.getProperties(),
isSSL
);
if (debug)
out.println("DEBUG: protocolConnect login" +
", host=" + host +
", user=" + user +
", password=<non-null>");
login(protocol, user, password);
protocol.addResponseHandler(this);
this.host = host;
this.user = user;
this.password = password;
synchronized (pool) {
pool.authenticatedConnections.addElement(protocol);
}
}
} catch (CommandFailedException cex) {
// login failure, close connection to server
if (protocol != null)
protocol.disconnect();
protocol = null;
throw new AuthenticationFailedException(
cex.getResponse().getRest());
} catch (ProtocolException pex) { // any other exception
throw new MessagingException(pex.getMessage(), pex);
} catch (IOException ioex) {
throw new MessagingException(ioex.getMessage(), ioex);
}
connected = true;
return true;
}
private void login(IMAPProtocol p, String u, String pw)
throws ProtocolException {
// turn on TLS if it's been enabled and is supported
if (enableStartTLS && p.hasCapability("STARTTLS")) {
p.startTLS();
// if startTLS succeeds, refresh capabilities
p.capability();
}
if (p.isAuthenticated())
return; // no need to login
/*
* Put a special "marker" in the capabilities list so we can
* detect if the server refreshed the capabilities in the OK
* response.
*/
p.getCapabilities().put("__PRELOGIN__", "");
String authzid;
if (authorizationID != null)
authzid = authorizationID;
else if (proxyAuthUser != null)
authzid = proxyAuthUser;
else
authzid = u;
if (enableSASL)
p.sasllogin(saslMechanisms, saslRealm, authzid, u, pw);
if (p.isAuthenticated())
; // SASL login succeeded, go to bottom
else if (p.hasCapability("AUTH=PLAIN") && !disableAuthPlain)
p.authplain(authzid, u, pw);
else if ((p.hasCapability("AUTH-LOGIN") ||
p.hasCapability("AUTH=LOGIN")) && !disableAuthLogin)
p.authlogin(u, pw);
else if (!p.hasCapability("LOGINDISABLED"))
p.login(u, pw);
else
throw new ProtocolException("No login methods supported!");
if (proxyAuthUser != null)
p.proxyauth(proxyAuthUser);
/*
* If marker is still there, capabilities haven't been refreshed,
* refresh them now.
*/
if (p.hasCapability("__PRELOGIN__")) {
try {
p.capability();
} catch (ConnectionException cex) {
throw cex; // rethrow connection failures
// XXX - assume connection has been closed
} catch (ProtocolException pex) {
// ignore other exceptions that "should never happen"
}
}
}
/**
* Set the user name that will be used for subsequent connections
* after this Store is first connected (for example, when creating
* a connection to open a Folder). This value is overridden
* by any call to the Store's connect method. <p>
*
* Some IMAP servers may provide an authentication ID that can
* be used for more efficient authentication for future connections.
* This authentication ID is provided in a server-specific manner
* not described here. <p>
*
* Most applications will never need to use this method.
*
* @since JavaMail 1.3.3
*/
public synchronized void setUsername(String user) {
this.user = user;
}
/**
* Set the password that will be used for subsequent connections
* after this Store is first connected (for example, when creating
* a connection to open a Folder). This value is overridden
* by any call to the Store's connect method. <p>
*
* Most applications will never need to use this method.
*
* @since JavaMail 1.3.3
*/
public synchronized void setPassword(String password) {
this.password = password;
}
/*
* Get a new authenticated protocol object for this Folder.
* Also store a reference to this folder in our list of
* open folders.
*/
IMAPProtocol getProtocol(IMAPFolder folder)
throws MessagingException {
IMAPProtocol p = null;
// keep looking for a connection until we get a good one
while (p == null) {
// New authenticated protocol objects are either acquired
// from the connection pool, or created when the pool is
// empty or no connections are available. None are available
// if the current pool size is one and the separate store
// property is set or the connection is in use.
synchronized (pool) {
// If there's none available in the pool,
// create a new one.
if (pool.authenticatedConnections.isEmpty() ||
(pool.authenticatedConnections.size() == 1 &&
(pool.separateStoreConnection || pool.storeConnectionInUse))) {
if (debug)
out.println("DEBUG: no connections in the pool, " +
"creating a new one");
try {
/*
* Some authentication systems use one time passwords
* or tokens, so each authentication request requires
* a new password. This "kludge" allows a callback
* to application code to get a new password.
*
* XXX - remove this when SASL support is added
*/
if (forcePasswordRefresh) {
InetAddress addr;
try {
addr = InetAddress.getByName(host);
} catch (UnknownHostException e) {
addr = null;
}
PasswordAuthentication pa =
session.requestPasswordAuthentication(addr, port,
name, null, user);
if (pa != null) {
user = pa.getUserName();
password = pa.getPassword();
}
}
// Use cached host, port and timeout values.
p = new IMAPProtocol(name, host, port,
session.getDebug(),
session.getDebugOut(),
session.getProperties(),
isSSL
);
// Use cached auth info
login(p, user, password);
} catch(Exception ex1) {
if (p != null)
try {
p.disconnect();
} catch (Exception ex2) { }
p = null;
}
if (p == null)
throw new MessagingException("connection failure");
} else {
if (debug)
out.println("DEBUG: connection available -- size: " +
pool.authenticatedConnections.size());
// remove the available connection from the Authenticated queue
p = (IMAPProtocol)pool.authenticatedConnections.lastElement();
pool.authenticatedConnections.removeElement(p);
// check if the connection is still live
long lastUsed = System.currentTimeMillis() - p.getTimestamp();
if (lastUsed > pool.serverTimeoutInterval) {
try {
// note that store is still the response handler,
// in case we get any alerts
p.noop();
} catch (ProtocolException pex) {
try {
p.removeResponseHandler(this);
p.disconnect();
} finally {
// don't let any exception stop us
p = null;
continue; // try again, from the top
}
}
}
// remove the store as a response handler.
p.removeResponseHandler(this);
}
// check if we need to look for client-side timeouts
timeoutConnections();
// Add folder to folder-list
if (folder != null) {
if (pool.folders == null)
pool.folders = new Vector();
pool.folders.addElement(folder);
}
}
}
return p;
}
/**
* Get this Store's protocol connection.
*
* When acquiring a store protocol object, it is important to
* use the following steps:
*
* IMAPProtocol p = null;
* try {
* p = getStoreProtocol();
* // perform the command
* } catch (ConnectionException cex) {
* throw new StoreClosedException(this, cex.getMessage());
* } catch (WhateverException ex) {
* // handle it
* } finally {
* releaseStoreProtocol(p);
* if (p == null) { // failed to get a Store connection
* // have to force Store to be closed
* cleanup();
* }
* }
*/
IMAPProtocol getStoreProtocol() throws ProtocolException {
IMAPProtocol p = null;
while (p == null) {
synchronized (pool) {
waitIfIdle();
// If there's no authenticated connections available create a
// new one and place it in the authenticated queue.
if (pool.authenticatedConnections.isEmpty()) {
if (pool.debug)
out.println("DEBUG: getStoreProtocol() - no connections " +
"in the pool, creating a new one");
try {
// Use cached host, port and timeout values.
p = new IMAPProtocol(name, host, port,
session.getDebug(),
session.getDebugOut(),
session.getProperties(),
isSSL
);
// Use cached auth info
login(p, user, password);
} catch(Exception ex1) {
if (p != null)
try {
p.logout();
} catch (Exception ex2) { }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -