📄 smtptransport.java
字号:
throw new MessagingException("Could not convert socket to TLS",
ioex);
}
}
/////// primitives ///////
/**
* Connect to server on port and start the SMTP protocol.
*/
private void openServer(String server, int port)
throws MessagingException {
if (debug)
out.println("DEBUG SMTP: trying to connect to host \"" + server +
"\", port " + port + ", isSSL " + isSSL);
try {
Properties props = session.getProperties();
serverSocket = SocketFetcher.getSocket(server, port,
props, "mail." + name, isSSL);
// socket factory may've chosen a different port,
// update it for the debug messages that follow
port = serverSocket.getPort();
initStreams();
int r = -1;
if ((r = readServerResponse()) != 220) {
serverSocket.close();
serverSocket = null;
serverOutput = null;
serverInput = null;
lineInputStream = null;
if (debug)
out.println("DEBUG SMTP: could not connect to host \"" +
server + "\", port: " + port +
", response: " + r + "\n");
throw new MessagingException(
"Could not connect to SMTP host: " + server +
", port: " + port +
", response: " + r);
} else {
if (debug)
out.println("DEBUG SMTP: connected to host \"" +
server + "\", port: " + port + "\n");
}
} catch (UnknownHostException uhex) {
throw new MessagingException("Unknown SMTP host: " + server, uhex);
} catch (IOException ioe) {
throw new MessagingException("Could not connect to SMTP host: " +
server + ", port: " + port, ioe);
}
}
/**
* Start the protocol to the server on serverSocket,
* assumed to be provided and connected by the caller.
*/
private void openServer() throws MessagingException {
int port = -1;
String server = "UNKNOWN";
try {
port = serverSocket.getPort();
server = serverSocket.getInetAddress().getHostName();
if (debug)
out.println("DEBUG SMTP: starting protocol to host \"" +
server + "\", port " + port);
initStreams();
int r = -1;
if ((r = readServerResponse()) != 220) {
serverSocket.close();
serverSocket = null;
serverOutput = null;
serverInput = null;
lineInputStream = null;
if (debug)
out.println("DEBUG SMTP: got bad greeting from host \"" +
server + "\", port: " + port +
", response: " + r + "\n");
throw new MessagingException(
"Got bad greeting from SMTP host: " + server +
", port: " + port +
", response: " + r);
} else {
if (debug)
out.println("DEBUG SMTP: protocol started to host \"" +
server + "\", port: " + port + "\n");
}
} catch (IOException ioe) {
throw new MessagingException(
"Could not start protocol to SMTP host: " +
server + ", port: " + port, ioe);
}
}
private void initStreams() throws IOException {
Properties props = session.getProperties();
PrintStream out = session.getDebugOut();
boolean debug = session.getDebug();
String s = props.getProperty("mail.debug.quote");
boolean quote = s != null && s.equalsIgnoreCase("true");
TraceInputStream traceInput =
new TraceInputStream(serverSocket.getInputStream(), out);
traceInput.setTrace(debug);
traceInput.setQuote(quote);
TraceOutputStream traceOutput =
new TraceOutputStream(serverSocket.getOutputStream(), out);
traceOutput.setTrace(debug);
traceOutput.setQuote(quote);
serverOutput =
new BufferedOutputStream(traceOutput);
serverInput =
new BufferedInputStream(traceInput);
lineInputStream = new LineInputStream(serverInput);
}
/**
* Send the command to the server. If the expected response code
* is not received, throw a MessagingException.
*
* @param cmd the command to send
* @param expect the expected response code
*
* @since JavaMail 1.4.1
*/
public synchronized void issueCommand(String cmd, int expect)
throws MessagingException {
sendCommand(cmd);
// if server responded with an unexpected return code,
// throw the exception, notifying the client of the response
if (readServerResponse() != expect)
throw new MessagingException(lastServerResponse);
}
/**
* Issue a command that's part of sending a message.
*/
private void issueSendCommand(String cmd, int expect)
throws MessagingException {
sendCommand(cmd);
// if server responded with an unexpected return code,
// throw the exception, notifying the client of the response
int ret;
if ((ret = readServerResponse()) != expect) {
// assume message was not sent to anyone,
// combine valid sent & unsent addresses
int vsl = validSentAddr == null ? 0 : validSentAddr.length;
int vul = validUnsentAddr == null ? 0 : validUnsentAddr.length;
Address[] valid = new Address[vsl + vul];
if (vsl > 0)
System.arraycopy(validSentAddr, 0, valid, 0, vsl);
if (vul > 0)
System.arraycopy(validUnsentAddr, 0, valid, vsl, vul);
validSentAddr = null;
validUnsentAddr = valid;
if (debug)
out.println("DEBUG SMTP: got response code " + ret +
", with response: " + lastServerResponse);
String _lsr = lastServerResponse; // else rset will nuke it
int _lrc = lastReturnCode;
if (serverSocket != null) // hasn't already been closed
issueCommand("RSET", 250);
lastServerResponse = _lsr; // restore, for get
lastReturnCode = _lrc;
throw new SMTPSendFailedException(cmd, ret, lastServerResponse,
exception, validSentAddr, validUnsentAddr, invalidAddr);
}
}
/**
* Send the command to the server and return the response code
* from the server.
*
* @since JavaMail 1.4.1
*/
public synchronized int simpleCommand(String cmd)
throws MessagingException {
sendCommand(cmd);
return readServerResponse();
}
/**
* Send the command to the server and return the response code
* from the server.
*
* @since JavaMail 1.4.1
*/
protected int simpleCommand(byte[] cmd) throws MessagingException {
assert Thread.holdsLock(this);
sendCommand(cmd);
return readServerResponse();
}
/**
* Sends command <code>cmd</code> to the server terminating
* it with <code>CRLF</code>.
*
* @since JavaMail 1.4.1
*/
protected void sendCommand(String cmd) throws MessagingException {
sendCommand(ASCIIUtility.getBytes(cmd));
}
private void sendCommand(byte[] cmdBytes) throws MessagingException {
assert Thread.holdsLock(this);
//if (debug)
//out.println("DEBUG SMTP SENT: " + new String(cmdBytes, 0));
try {
serverOutput.write(cmdBytes);
serverOutput.write(CRLF);
serverOutput.flush();
} catch (IOException ex) {
throw new MessagingException("Can't send command to SMTP host", ex);
}
}
/**
* Reads server reponse returning the <code>returnCode</code>
* as the number. Returns -1 on failure. Sets
* <code>lastServerResponse</code> and <code>lastReturnCode</code>.
*
* @return server response code
*
* @since JavaMail 1.4.1
*/
protected int readServerResponse() throws MessagingException {
assert Thread.holdsLock(this);
String serverResponse = "";
int returnCode = 0;
StringBuffer buf = new StringBuffer(100);
// read the server response line(s) and add them to the buffer
// that stores the response
try {
String line = null;
do {
line = lineInputStream.readLine();
if (line == null) {
serverResponse = buf.toString();
if (serverResponse.length() == 0)
serverResponse = "[EOF]";
lastServerResponse = serverResponse;
lastReturnCode = -1;
if (debug)
out.println("DEBUG SMTP: EOF: " + serverResponse);
return -1;
}
buf.append(line);
buf.append("\n");
} while (isNotLastLine(line));
serverResponse = buf.toString();
} catch (IOException ioex) {
if (debug)
out.println("DEBUG SMTP: exception reading response: " + ioex);
//ioex.printStackTrace(out);
lastServerResponse = "";
lastReturnCode = 0;
throw new MessagingException("Exception reading response", ioex);
//returnCode = -1;
}
// print debug info
//if (debug)
//out.println("DEBUG SMTP RCVD: " + serverResponse);
// parse out the return code
if (serverResponse != null && serverResponse.length() >= 3) {
try {
returnCode = Integer.parseInt(serverResponse.substring(0, 3));
} catch (NumberFormatException nfe) {
try {
close();
} catch (MessagingException mex) {
// thrown by close()--ignore, will close() later anyway
if (debug)
mex.printStackTrace(out);
}
returnCode = -1;
} catch (StringIndexOutOfBoundsException ex) {
//if (debug) ex.printStackTrace(out);
try {
close();
} catch (MessagingException mex) {
// thrown by close()--ignore, will close() later anyway
if (debug)
mex.printStackTrace(out);
}
returnCode = -1;
}
} else {
returnCode = -1;
}
if (returnCode == -1 && debug)
out.println("DEBUG SMTP: bad server response: " + serverResponse);
lastServerResponse = serverResponse;
lastReturnCode = returnCode;
return returnCode;
}
/**
* Check if we're in the connected state. Don't bother checking
* whether the server is still alive, that will be detected later.
*
* @exception IllegalStateException if not connected
*
* @since JavaMail 1.4.1
*/
protected void checkConnected() {
if (!super.isConnected())
throw new IllegalStateException("Not connected");
}
// tests if the <code>line</code> is an intermediate line according to SMTP
private boolean isNotLastLine(String line) {
return line != null && line.length() >= 4 && line.charAt(3) == '-';
}
// wraps an address in "<>"'s if necessary
private String normalizeAddress(String addr) {
if ((!addr.startsWith("<")) && (!addr.endsWith(">")))
return "<" + addr + ">";
else
return addr;
}
/**
* Return true if the SMTP server supports the specified service
* extension. Extensions are reported as results of the EHLO
* command when connecting to the server. See
* <A HREF="http://www.ietf.org/rfc/rfc1869.txt">RFC 1869</A>
* and other RFCs that define specific extensions.
*
* @param ext the service extension name
* @return true if the extension is supported
*
* @since JavaMail 1.3.2
*/
public boolean supportsExtension(String ext) {
return extMap != null &&
extMap.get(ext.toUpperCase(Locale.ENGLISH)) != null;
}
/**
* Return the parameter the server provided for the specified
* service extension, or null if the extension isn't supported.
*
* @param ext the service extension name
* @return the extension parameter
*
* @since JavaMail 1.3.2
*/
public String getExtensionParameter(String ext) {
return extMap == null ? null :
(String)extMap.get(ext.toUpperCase(Locale.ENGLISH));
}
/**
* Does the server we're connected to support the specified
* authentication mechanism? Uses the extension information
* returned by the server from the EHLO command.
*
* @param auth the authentication mechanism
* @return true if the authentication mechanism is supported
*
* @since JavaMail 1.4.1
*/
protected boolean supportsAuthentication(String auth) {
assert Thread.holdsLock(this);
if (extMap == null)
return false;
String a = (String)extMap.get("AUTH");
if (a == null)
return false;
StringTokenizer st = new StringTokenizer(a);
while (st.hasMoreTokens()) {
String tok = st.nextToken();
if (tok.equalsIgnoreCase(auth))
return true;
}
return false;
}
private static char[] hexchar = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
/**
* Convert a string to RFC 1891 xtext format.
*
* <p><pre>
* xtext = *( xchar / hexchar )
*
* xchar = any ASCII CHAR between "!" (33) and "~" (126) inclusive,
* except for "+" and "=".
*
* ; "hexchar"s are intended to encode octets that cannot appear
* ; as ASCII characters within an esmtp-value.
*
* hexchar = ASCII "+" immediately followed by two upper case
* hexadecimal digits
* </pre></p>
*
* @since JavaMail 1.4.1
*/
protected static String xtext(String s) {
StringBuffer sb = null;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 128) // not ASCII
throw new IllegalArgumentException(
"Non-ASCII character in SMTP submitter: " + s);
if (c < '!' || c > '~' || c == '+' || c == '=') {
if (sb == null) {
sb = new StringBuffer(s.length() + 4);
sb.append(s.substring(0, i));
}
sb.append('+');
sb.append(hexchar[(((int)c)& 0xf0) >> 4]);
sb.append(hexchar[((int)c)& 0x0f]);
} else {
if (sb != null)
sb.append(c);
}
}
return sb != null ? sb.toString() : s;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -