📄 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 + -