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

📄 smtptransport.java

📁 java Email you can use it to send email to others
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
		if (resp == 530) {		    startTLS();		    resp = simpleCommand("AUTH LOGIN");		}		/*		 * Wrap a BASE64Encoder around a ByteArrayOutputstream		 * to craft b64 encoded username and password strings.		 *		 * Also note that unlike the B64 definition in MIME, CRLFs 		 * should *not* be inserted during the encoding process.		 * So I use Integer.MAX_VALUE (0x7fffffff (> 1G)) as the		 * bytesPerLine, which should be sufficiently large!		 */		try {		    ByteArrayOutputStream bos = new ByteArrayOutputStream();		    OutputStream b64os =				new BASE64EncoderStream(bos, Integer.MAX_VALUE);		    if (resp == 334) {			// obtain b64 encoded bytes			b64os.write(ASCIIUtility.getBytes(user));			b64os.flush(); 	// complete the encoding			// send username			resp = simpleCommand(bos.toByteArray());			bos.reset(); 	// reset buffer		    }		    if (resp == 334) {			// obtain b64 encoded bytes			b64os.write(ASCIIUtility.getBytes(passwd));			b64os.flush(); 	// complete the encoding			// send passwd			resp = simpleCommand(bos.toByteArray());			bos.reset(); 	// reset buffer		    }		} catch (IOException ex) {	// should never happen, ignore		} finally {		    if (resp != 235) {			closeConnection();			return false;		    }		}	    } else if (supportsAuthentication("PLAIN")) {		// XXX - could use "initial response" capability		int resp = simpleCommand("AUTH PLAIN");		try {		    ByteArrayOutputStream bos = new ByteArrayOutputStream();		    OutputStream b64os =				new BASE64EncoderStream(bos, Integer.MAX_VALUE);		    if (resp == 334) {			// send "<NUL>user<NUL>passwd"			// XXX - we don't send an authorization identity			b64os.write(0);			b64os.write(ASCIIUtility.getBytes(user));			b64os.write(0);			b64os.write(ASCIIUtility.getBytes(passwd));			b64os.flush(); 	// complete the encoding			// send username			resp = simpleCommand(bos.toByteArray());		    }		} catch (IOException ex) {	// should never happen, ignore		} finally {		    if (resp != 235) {			closeConnection();			return false;		    }		}	    } else if (supportsAuthentication("DIGEST-MD5") &&		    (md5 = getMD5()) != null) {		int resp = simpleCommand("AUTH DIGEST-MD5");		try {		    if (resp == 334) {			byte[] b = md5.authClient(host, user, passwd,					    getSASLRealm(), lastServerResponse);			resp = simpleCommand(b);			if (resp == 334) { // client authenticated by server			    if (!md5.authServer(lastServerResponse)) {				// server NOT authenticated by client !!!				resp = -1;			    } else {				// send null response				resp = simpleCommand(new byte[0]);			    }			}		    }		} catch (Exception ex) {	// should never happen, ignore		    if (debug)			out.println("DEBUG SMTP: DIGEST-MD5: " + ex);		} finally {		    if (resp != 235) {			closeConnection();			return false;		    }		}	    }	}	// we connected correctly	return true;    }    /**     * Send the Message to the specified list of addresses.<p>     *     * If all the <code>addresses</code> succeed the SMTP check     * using the <code>RCPT TO:</code> command, we attempt to send the message.     * A TransportEvent of type MESSAGE_DELIVERED is fired indicating the     * successful submission of a message to the SMTP host.<p>     *     * If some of the <code>addresses</code> fail the SMTP check,     * and the <code>mail.stmp.sendpartial</code> property is not set,     * sending is aborted. The TransportEvent of type MESSAGE_NOT_DELIVERED     * is fired containing the valid and invalid addresses. The     * SendFailedException is also thrown. <p>     *     * If some of the <code>addresses</code> fail the SMTP check,     * and the <code>mail.stmp.sendpartial</code> property is set to true,     * the message is sent. The TransportEvent of type     * MESSAGE_PARTIALLY_DELIVERED     * is fired containing the valid and invalid addresses. The     * SMTPSendFailedException is also thrown. <p>     *     * MessagingException is thrown if the message can't write out     * an RFC822-compliant stream using its <code>writeTo</code> method. <p>     *     * @param message	The MimeMessage to be sent     * @param addresses	List of addresses to send this message to     * @see 		javax.mail.event.TransportEvent     * @exception       SMTPSendFailedException if the send failed because of     *			an SMTP command error     * @exception       SendFailedException if the send failed because of     *			invalid addresses.     * @exception       MessagingException if the connection is dead     *                  or not in the connected state or if the message is     *                  not a MimeMessage.     */    public synchronized void sendMessage(Message message, Address[] addresses)		    throws MessagingException, SendFailedException {	checkConnected();	// check if the message is a valid MIME/RFC822 message and that	// it has all valid InternetAddresses; fail if not        if (!(message instanceof MimeMessage)) {	    if (debug)		out.println("DEBUG SMTP: Can only send RFC822 msgs");	    throw new MessagingException("SMTP can only send RFC822 messages");	}	for (int i = 0; i < addresses.length; i++) {	    if (!(addresses[i] instanceof InternetAddress)) {		throw new MessagingException(addresses[i] +					     " is not an InternetAddress");	    }	}	this.message = (MimeMessage)message;	this.addresses = addresses;	validUnsentAddr = addresses;	// until we know better	expandGroups();	boolean use8bit = false;	if (message instanceof SMTPMessage)	    use8bit = ((SMTPMessage)message).getAllow8bitMIME();	if (!use8bit) {	    String ebStr =		    session.getProperty("mail." + name + ".allow8bitmime");	    use8bit = ebStr != null && ebStr.equalsIgnoreCase("true");	}	if (debug)	    out.println("DEBUG SMTP: use8bit " + use8bit);	if (use8bit && supportsExtension("8BITMIME")) {	    if (convertTo8Bit(this.message)) {		// in case we made any changes, save those changes		// XXX - this will change the Message-ID		try {		    this.message.saveChanges();		} catch (MessagingException mex) {		    // ignore it		}	    }	}	try {	    mailFrom();	    rcptTo();	    this.message.writeTo(data(), ignoreList);	    finishData();	    if (sendPartiallyFailed) {		// throw the exception,		// fire TransportEvent.MESSAGE_PARTIALLY_DELIVERED event		if (debug)		    out.println("DEBUG SMTP: Sending partially failed " +			"because of invalid destination addresses");		notifyTransportListeners(			TransportEvent.MESSAGE_PARTIALLY_DELIVERED,			validSentAddr, validUnsentAddr, invalidAddr,			this.message);		throw new SMTPSendFailedException(".", lastReturnCode,				lastServerResponse, exception,				validSentAddr, validUnsentAddr, invalidAddr);	    }	    notifyTransportListeners(TransportEvent.MESSAGE_DELIVERED,				     validSentAddr, validUnsentAddr,				     invalidAddr, this.message);	} catch (MessagingException mex) {	    if (debug)		mex.printStackTrace(out);	    notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED,				     validSentAddr, validUnsentAddr,				     invalidAddr, this.message);	    throw mex;	} catch (IOException ex) {	    if (debug)		ex.printStackTrace(out);	    // if we catch an IOException, it means that we want	    // to drop the connection so that the message isn't sent	    try {		closeConnection();	    } catch (MessagingException mex) { /* ignore it */ }	    notifyTransportListeners(TransportEvent.MESSAGE_NOT_DELIVERED,				     validSentAddr, validUnsentAddr,				     invalidAddr, this.message);	    throw new MessagingException("IOException while sending message",					 ex);	} finally {	    // no reason to keep this data around	    validSentAddr = validUnsentAddr = invalidAddr = null;	    this.addresses = null;	    this.message = null;	    this.exception = null;	    sendPartiallyFailed = false;	}    }    /**     * Close the Transport and terminate the connection to the server.     */    public synchronized void close() throws MessagingException {	if (!super.isConnected()) // Already closed.	    return;	try {	    if (serverSocket != null) {		sendCommand("QUIT");		if (quitWait) {		    int resp = readServerResponse();		    if (resp != 221 && resp != -1)			out.println("DEBUG SMTP: QUIT failed with " + resp);		}	    }	} finally {	    closeConnection();	}    }    private void closeConnection() throws MessagingException {	try {	    if (serverSocket != null)		serverSocket.close();	} catch (IOException ioex) {	    // shouldn't happen	    throw new MessagingException("Server Close Failed", ioex);	} finally {	    serverSocket = null;	    serverOutput = null;	    serverInput = null;	    lineInputStream = null;	    if (super.isConnected())	// only notify if already connected		super.close();	}    }    /**     * Check whether the transport is connected. Override superclass     * method, to actually ping our server connection.     */    public synchronized boolean isConnected() {	if (!super.isConnected())	    // if we haven't been connected at all, don't bother with NOOP	    return false;	try {	    // sendmail may respond slowly to NOOP after many requests	    // so if mail.smtp.userset is set we use RSET instead of NOOP.	    if (useRset)		sendCommand("RSET");	    else		sendCommand("NOOP");	    int resp = readServerResponse();	    // NOOP should return 250 on success, however, SIMS 3.2 returns	    // 200, so we work around it.	    //	    // Hotmail doesn't implement the NOOP command at all so assume	    // any kind of response means we're still connected.	    // That is, any response except 421, which means the server	    // is shutting down the connection.	    //	    if (resp >= 0 && resp != 421) {		return true;	    } else {		try {		    closeConnection();		} catch (MessagingException mex) { }	// ignore it		return false;	    }	} catch (Exception ex) {	    try {		closeConnection();	    } catch (MessagingException mex) { }	// ignore it	    return false;	}    }    /**     * Expand any group addresses.     */    private void expandGroups() {	Vector groups = null;	for (int i = 0; i < addresses.length; i++) {	    InternetAddress a = (InternetAddress)addresses[i];	    if (a.isGroup()) {		if (groups == null) {		    // first group, catch up with where we are		    groups = new Vector();		    for (int k = 0; k < i; k++)			groups.addElement(addresses[k]);		}		// parse it and add each individual address		try {		    InternetAddress[] ia = a.getGroup(true);		    if (ia != null) {			for (int j = 0; j < ia.length; j++)			    groups.addElement(ia[j]);		    } else			groups.addElement(a);		} catch (ParseException pex) {		    // parse failed, add the whole thing		    groups.addElement(a);		}	    } else {		// if we've started accumulating a list, add this to it		if (groups != null)		    groups.addElement(a);	    }	}	// if we have a new list, convert it back to an array	if (groups != null) {	    InternetAddress[] newa = new InternetAddress[groups.size()];	    groups.copyInto(newa);	    addresses = newa;	}    }    /**     * If the Part is a text part and has a Content-Transfer-Encoding     * of "quoted-printable" or "base64", and it obeys the rules for     * "8bit" encoding, change the encoding to "8bit".  If the part is     * a multipart, recursively process all its parts.     *     * @return	true	if any changes were made     *     * XXX - This is really quite a hack.     */    private boolean convertTo8Bit(MimePart part) {	boolean changed = false;	try {	    if (part.isMimeType("text/*")) {		String enc = part.getEncoding();		if (enc != null && (enc.equalsIgnoreCase("quoted-printable") ||		    enc.equalsIgnoreCase("base64"))) {		    InputStream is = part.getInputStream();		    if (is8Bit(is)) {			/*			 * If the message was created using an InputStream			 * then we have to extract the content as an object			 * and set it back as an object so that the content			 * will be re-encoded.			 *			 * If the message was not created using an InputStream,			 * the following should have no effect.			 */			part.setContent(part.getContent(),					part.getContentType());			part.setHeader("Content-Transfer-Encoding", "8bit");			changed = true;		    }		}	    } else if (part.isMimeType("multipart/*")) {		MimeMultipart mp = (MimeMultipart)part.getContent();		int count = mp.getCount();		for (int i = 0; i < count; i++) {		    if (convertTo8Bit((MimePart)mp.getBodyPart(i)))			changed = true;		}	    }	} catch (IOException ioex) {	    // any exception causes us to give up	} catch (MessagingException mex) {	    // any exception causes us to give up	}	return changed;    }    /**     * Check whether the data in the given InputStream follows the     * rules for 8bit text.  Lines have to be 998 characters or less     * and no NULs are allowed.  CR and LF must occur in pairs but we     * don't check that because we assume this is text and we convert     * all CR/LF combinations into canonical CRLF later.     */    private boolean is8Bit(InputStream is) {	int b;	int linelen = 0;	boolean need8bit = false;	try {	    while ((b = is.read()) >= 0) {		b &= 0xff;		if (b == '\r' || b == '\n')		    linelen = 0;		else if (b == 0)		    return false;		else {		    linelen++;		    if (linelen > 998)	// 1000 - CRLF			return false;		}		if (b > 0x7f)		    need8bit = true;	    }	} catch (IOException ex) {	    return false;	}	if (debug && need8bit)	    out.println("DEBUG SMTP: found an 8bit part");	return need8bit;    }    protected void finalize() throws Throwable {	super.finalize();

⌨️ 快捷键说明

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