⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smtptransport.java

📁 java Email you can use it to send email to others
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License").  You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. * Sun designates this particular file as subject to the "Classpath" exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code.  If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: "Portions Copyrighted [year] * [name of copyright owner]" * * Contributor(s): * * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license."  If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above.  However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. *//* * @(#)SMTPTransport.java	1.89 07/07/03 */package com.sun.mail.smtp;import java.io.*;import java.net.*;import java.util.*;import javax.mail.*;import javax.mail.event.*;import javax.mail.internet.*;import com.sun.mail.util.*;/** * This class implements the Transport abstract class using SMTP for * message submission and transport. <p> * * See the <a href="package-summary.html">com.sun.mail.smtp</a> package * documentation for further information on the SMTP protocol provider. <p> * * This class includes many protected methods that allow a subclass to * extend this class and add support for non-standard SMTP commands. * The {@link #issueCommand} and {@link #sendCommand} methods can be * used to send simple SMTP commands.  Other methods such as the * {@link #mailFrom} and {@link #data} methods can be overridden to * insert new commands before or after the corresponding SMTP commands. * For example, a subclass could do this to send the XACT command * before sending the DATA command: * <pre> *	protected OutputStream data() throws MessagingException { *	    if (supportsExtension("XACCOUNTING")) *	        issueCommand("XACT", 25); *	    return super.data(); *	} * </pre> * * @author Max Spivak * @author Bill Shannon * @author Dean Gibson (DIGEST-MD5 authentication) * @version 1.89, 07/07/03 * * @see javax.mail.event.ConnectionEvent * @see javax.mail.event.TransportEvent */public class SMTPTransport extends Transport {    private String name = "smtp";	// Name of this protocol    private int defaultPort = 25;	// default SMTP port    private boolean isSSL = false;	// use SSL?    // Following fields valid only during the sendMessage method.    private MimeMessage message;	// Message to be sent    private Address[] addresses;	// Addresses to which to send the msg    // Valid sent, valid unsent and invalid addresses    private Address[] validSentAddr, validUnsentAddr, invalidAddr;    // Did we send the message even though some addresses were invalid?    private boolean sendPartiallyFailed = false;    // If so, here's an exception we need to throw    private MessagingException exception;    // stream where message data is written    private SMTPOutputStream dataStream;    // Map of SMTP service extensions supported by server, if EHLO used.    private Hashtable extMap;    private boolean quitWait = false;	// true if we should wait    private String saslRealm = UNKNOWN;    private boolean reportSuccess;	// throw an exception even on success    private boolean useStartTLS;	// use STARTTLS command    private boolean useRset;		// use RSET instead of NOOP    private PrintStream out;		// debug output stream    private String localHostName;	// our own host name    private String lastServerResponse;	// last SMTP response    private int lastReturnCode;		// last SMTP return code    /** Headers that should not be included when sending */    private static final String[] ignoreList = { "Bcc", "Content-Length" };    private static final byte[] CRLF = { (byte)'\r', (byte)'\n' };    private static final String UNKNOWN = "UNKNOWN";	// place holder    /**     * Constructor that takes a Session object and a URLName     * that represents a specific SMTP server.     */    public SMTPTransport(Session session, URLName urlname) {	this(session, urlname, "smtp", 25, false);    }    /**     * Constructor used by this class and by SMTPSSLTransport subclass.     */    protected SMTPTransport(Session session, URLName urlname,				String name, int defaultPort, boolean isSSL) {	super(session, urlname);	if (urlname != null)	    name = urlname.getProtocol();	this.name = name;	this.defaultPort = defaultPort;	this.isSSL = isSSL;	out = session.getDebugOut();	// setting mail.smtp.quitwait to false causes us to not wait for the	// response from the QUIT command	String s = session.getProperty("mail." + name + ".quitwait");	quitWait = s == null || s.equalsIgnoreCase("true");	// mail.smtp.reportsuccess causes us to throw an exception on success	s = session.getProperty("mail." + name + ".reportsuccess");	reportSuccess = s != null && s.equalsIgnoreCase("true");	// mail.smtp.starttls.enable enables use of STARTTLS command	s = session.getProperty("mail." + name + ".starttls.enable");	useStartTLS = s != null && s.equalsIgnoreCase("true");	// mail.smtp.userset causes us to use RSET instead of NOOP	// for isConnected	s = session.getProperty("mail." + name + ".userset");	useRset = s != null && s.equalsIgnoreCase("true");    }    /**     * Get the name of the local host, for use in the EHLO and HELO commands.     * The property mail.smtp.localhost overrides mail.smtp.localaddress,     * which overrides what InetAddress would tell us.     */    public synchronized String getLocalHost() {	try {	    // get our hostname and cache it for future use	    if (localHostName == null || localHostName.length() <= 0)		localHostName =			session.getProperty("mail." + name + ".localhost");	    if (localHostName == null || localHostName.length() <= 0)		localHostName =			session.getProperty("mail." + name + ".localaddress");	    if (localHostName == null || localHostName.length() <= 0) {		InetAddress localHost = InetAddress.getLocalHost();		localHostName = localHost.getHostName();		// if we can't get our name, use local address literal		if (localHostName == null)		    // XXX - not correct for IPv6		    localHostName = "[" + localHost.getHostAddress() + "]";	    }	} catch (UnknownHostException uhex) {	}	return localHostName;    }    /**     * Set the name of the local host, for use in the EHLO and HELO commands.     *     * @since JavaMail 1.3.1     */    public synchronized void setLocalHost(String localhost) {	localHostName = localhost;    }    /**     * Start the SMTP protocol on the given socket, which was already     * connected by the caller.  Useful for implementing the SMTP ATRN     * command (RFC 2645) where an existing connection is used when     * the server reverses roles and becomes the client.     *     * @since JavaMail 1.3.3     */    public synchronized void connect(Socket socket) throws MessagingException {	serverSocket = socket;	super.connect();    }    /**     * Gets the SASL realm to be used for DIGEST-MD5 authentication.     *     * @return	the name of the realm to use for SASL authentication.     *     * @since JavaMail 1.3.1     */    public synchronized String getSASLRealm() {	if (saslRealm == UNKNOWN) {	    saslRealm = session.getProperty("mail." + name + ".sasl.realm");	    if (saslRealm == null)	// try old name		saslRealm = session.getProperty("mail." + name + ".saslrealm");	}	return saslRealm;    }    /**     * Sets the SASL realm to be used for DIGEST-MD5 authentication.     *     * @param	saslRealm	the name of the realm to use for     *				SASL authentication.     *     * @since JavaMail 1.3.1     */    public synchronized void setSASLRealm(String saslRealm) {	this.saslRealm = saslRealm;    }    /**     * Should we report even successful sends by throwing an exception?     * If so, a <code>SendFailedException</code> will always be thrown and     * an {@link com.sun.mail.smtp.SMTPAddressSucceededException     * SMTPAddressSucceededException} will be included in the exception     * chain for each successful address, along with the usual     * {@link com.sun.mail.smtp.SMTPAddressFailedException     * SMTPAddressFailedException} for each unsuccessful address.     *     * @return	true if an exception will be thrown on successful sends.     *     * @since JavaMail 1.3.2     */    public synchronized boolean getReportSuccess() {	return reportSuccess;    }    /**     * Set whether successful sends should be reported by throwing     * an exception.     *     * @param	reportSuccess	should we throw an exception on success?     *     * @since JavaMail 1.3.2     */    public synchronized void setReportSuccess(boolean reportSuccess) {	this.reportSuccess = reportSuccess;    }    /**     * Should we use the STARTTLS command to secure the connection     * if the server supports it?     *     * @return	true if the STARTTLS command will be used     *     * @since JavaMail 1.3.2     */    public synchronized boolean getStartTLS() {	return useStartTLS;    }    /**     * Set whether the STARTTLS command should be used.     *     * @param	useStartTLS	should we use the STARTTLS command?     *     * @since JavaMail 1.3.2     */    public synchronized void setStartTLS(boolean useStartTLS) {	this.useStartTLS = useStartTLS;    }    /**     * Should we use the RSET command instead of the NOOP command     * in the @{link #isConnected isConnected} method?     *     * @return	true if RSET will be used     *     * @since JavaMail 1.4     */    public synchronized boolean getUseRset() {	return useRset;    }    /**     * Set whether the RSET command should be used instead of the     * NOOP command in the @{link #isConnected isConnected} method.     *     * @param	useRset	should we use the RSET command?     *     * @since JavaMail 1.4     */    public synchronized void setUseRset(boolean useRset) {	this.useRset = useRset;    }    /**     * Return the last response we got from the server.     * A failed send is often followed by an RSET command,     * but the response from the RSET command is not saved.     * Instead, this returns the response from the command     * before the RSET command.     *     * @return	last response from server     *     * @since JavaMail 1.3.2     */    public synchronized String getLastServerResponse() {	return lastServerResponse;    }    /**     * Return the return code from the last response we got from the server.     *     * @return	return code from last response from server     *     * @since JavaMail 1.4.1     */    public synchronized int getLastReturnCode() {	return lastReturnCode;    }    private DigestMD5 md5support;    private synchronized DigestMD5 getMD5() {	if (md5support == null)	    md5support = new DigestMD5(debug ? out : null);	return md5support;    }    /**     * Performs the actual protocol-specific connection attempt.     * Will attempt to connect to "localhost" if the host was null. <p>     *     * Unless mail.smtp.ehlo is set to false, we'll try to identify     * ourselves using the ESMTP command EHLO.     *     * If mail.smtp.auth is set to true, we insist on having a username     * and password, and will try to authenticate ourselves if the server     * supports the AUTH extension (RFC 2554).     *     * @param	host		  the name of the host to connect to     * @param	port		  the port to use (-1 means use default port)     * @param	user		  the name of the user to login as     * @param	passwd	  	  the user's password     * @return	true if connection successful, false if authentication failed     * @exception MessagingException	for non-authentication failures     */    protected boolean protocolConnect(String host, int port, String user,			      String passwd) throws MessagingException {	// setting mail.smtp.ehlo to false disables attempts to use EHLO	String ehloStr = session.getProperty("mail." + name + ".ehlo");	boolean useEhlo = ehloStr == null || !ehloStr.equalsIgnoreCase("false");	// setting mail.smtp.auth to true enables attempts to use AUTH	String authStr = session.getProperty("mail." + name + ".auth");	boolean useAuth = authStr != null && authStr.equalsIgnoreCase("true");	DigestMD5 md5;	if (debug)	    out.println("DEBUG SMTP: useEhlo " + useEhlo +				", useAuth " + useAuth);	/*	 * If mail.smtp.auth is set, make sure we have a valid username	 * and password, even if we might not end up using it (e.g.,	 * because the server doesn't support ESMTP or doesn't support	 * the AUTH extension).	 */	if (useAuth && (user == null || passwd == null))	    return false;	/*	 * If port is not specified, set it to value of mail.smtp.port         * property if it exists, otherwise default to 25.	 */        if (port == -1) {	    String portstring = session.getProperty("mail." + name + ".port");	    if (portstring != null) {		port = Integer.parseInt(portstring);	    } else {		port = defaultPort;	    }	}	if (host == null || host.length() == 0)	    host = "localhost";	boolean succeed = false;	if (serverSocket != null)	    openServer();	// only happens from connect(socket)	else	    openServer(host, port);	if (useEhlo)	    succeed = ehlo(getLocalHost());	if (!succeed)	    helo(getLocalHost());	if (useStartTLS && supportsExtension("STARTTLS")) {	    startTLS();	    /*	     * Have to issue another EHLO to update list of extensions	     * supported, especially authentication mechanisms.	     * Don't know if this could ever fail, but we ignore failure.	     */	    ehlo(getLocalHost());	}	if ((useAuth || (user != null && passwd != null)) &&	      (supportsExtension("AUTH") || supportsExtension("AUTH=LOGIN"))) {	    if (debug) {		out.println("DEBUG SMTP: Attempt to authenticate");		if (!supportsAuthentication("LOGIN") &&			supportsExtension("AUTH=LOGIN"))		    out.println("DEBUG SMTP: use AUTH=LOGIN hack");	    }	    // if authentication fails, close connection and return false	    if (supportsAuthentication("LOGIN") ||		    supportsExtension("AUTH=LOGIN")) {		// XXX - could use "initial response" capability		int resp = simpleCommand("AUTH LOGIN");		/*		 * A 530 response indicates that the server wants us to		 * issue a STARTTLS command first.  Do that and try again.		 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -