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

📄 smtptransport.java

📁 此源码是在sun站点上提供的javamail基础上改进。用来解决中文邮件或很多国际间邮件乱码问题。版权属于sun公司。不过当你开发webmail程序时做邮件展示时
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	    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 + -