📄 remotedelivery.java
字号:
.append(mail.getName()) .append(": "); out.print(logBuffer.toString()); if (isDebug) ex.printStackTrace(out); log(sout.toString()); if (!permanent) { if (!mail.getState().equals(Mail.ERROR)) { mail.setState(Mail.ERROR); mail.setErrorMessage("0"); mail.setLastUpdated(new Date()); } int retries = Integer.parseInt(mail.getErrorMessage()); if (retries < maxRetries) { logBuffer = new StringBuffer(128) .append("Storing message ") .append(mail.getName()) .append(" into outgoing after ") .append(retries) .append(" retries"); log(logBuffer.toString()); ++retries; mail.setErrorMessage(retries + ""); mail.setLastUpdated(new Date()); return false; } else { logBuffer = new StringBuffer(128) .append("Bouncing message ") .append(mail.getName()) .append(" after ") .append(retries) .append(" retries"); log(logBuffer.toString()); } } if (mail.getSender() == null) { log("Null Sender: no bounce will be generated for " + mail.getName()); return true; } if (bounceProcessor != null) { // do the new DSN bounce // setting attributes for DSN mailet mail.setAttribute("delivery-error", ex); mail.setState(bounceProcessor); // re-insert the mail into the spool for getting it passed to the dsn-processor MailetContext mc = getMailetContext(); try { mc.sendMail(mail); } catch (MessagingException e) { // we shouldn't get an exception, because the mail was already processed log("Exception re-inserting failed mail: ", e); } } else { // do an old style bounce bounce(mail, ex); } return true; } private void bounce(Mail mail, MessagingException ex) { StringWriter sout = new StringWriter(); PrintWriter out = new PrintWriter(sout, true); String machine = "[unknown]"; try { InetAddress me = InetAddress.getLocalHost(); machine = me.getHostName(); } catch(Exception e){ machine = "[address unknown]"; } StringBuffer bounceBuffer = new StringBuffer(128) .append("Hi. This is the James mail server at ") .append(machine) .append("."); out.println(bounceBuffer.toString()); out.println("I'm afraid I wasn't able to deliver your message to the following addresses."); out.println("This is a permanent error; I've given up. Sorry it didn't work out. Below"); out.println("I include the list of recipients and the reason why I was unable to deliver"); out.println("your message."); out.println(); for (Iterator i = mail.getRecipients().iterator(); i.hasNext(); ) { out.println(i.next()); } if (ex.getNextException() == null) { out.println(ex.getMessage().trim()); } else { Exception ex1 = ex.getNextException(); if (ex1 instanceof SendFailedException) { out.println("Remote mail server told me: " + ex1.getMessage().trim()); } else if (ex1 instanceof UnknownHostException) { out.println("Unknown host: " + ex1.getMessage().trim()); out.println("This could be a DNS server error, a typo, or a problem with the recipient's mail server."); } else if (ex1 instanceof ConnectException) { //Already formatted as "Connection timed out: connect" out.println(ex1.getMessage().trim()); } else if (ex1 instanceof SocketException) { out.println("Socket exception: " + ex1.getMessage().trim()); } else { out.println(ex1.getMessage().trim()); } } out.println(); log("Sending failure message " + mail.getName()); try { getMailetContext().bounce(mail, sout.toString()); } catch (MessagingException me) { log("Encountered unexpected messaging exception while bouncing message: " + me.getMessage()); } catch (Exception e) { log("Encountered unexpected exception while bouncing message: " + e.getMessage()); } } public String getMailetInfo() { return "RemoteDelivery Mailet"; } /** * For this message, we take the list of recipients, organize these into distinct * servers, and duplicate the message for each of these servers, and then call * the deliver (messagecontainer) method for each server-specific * messagecontainer ... that will handle storing it in the outgoing queue if needed. * * @param mail org.apache.mailet.Mail */ public void service(Mail mail) throws MessagingException{ // Do I want to give the internal key, or the message's Message ID if (isDebug) { log("Remotely delivering mail " + mail.getName()); } Collection recipients = mail.getRecipients(); if (gatewayServer == null) { // Must first organize the recipients into distinct servers (name made case insensitive) Hashtable targets = new Hashtable(); for (Iterator i = recipients.iterator(); i.hasNext();) { MailAddress target = (MailAddress)i.next(); String targetServer = target.getHost().toLowerCase(Locale.US); Collection temp = (Collection)targets.get(targetServer); if (temp == null) { temp = new ArrayList(); targets.put(targetServer, temp); } temp.add(target); } //We have the recipients organized into distinct servers... put them into the //delivery store organized like this... this is ultra inefficient I think... // Store the new message containers, organized by server, in the outgoing mail repository String name = mail.getName(); for (Iterator i = targets.keySet().iterator(); i.hasNext(); ) { String host = (String) i.next(); Collection rec = (Collection) targets.get(host); if (isDebug) { StringBuffer logMessageBuffer = new StringBuffer(128) .append("Sending mail to ") .append(rec) .append(" on host ") .append(host); log(logMessageBuffer.toString()); } mail.setRecipients(rec); StringBuffer nameBuffer = new StringBuffer(128) .append(name) .append("-to-") .append(host); mail.setName(nameBuffer.toString()); outgoing.store(mail); //Set it to try to deliver (in a separate thread) immediately (triggered by storage) } } else { // Store the mail unaltered for processing by the gateway server(s) if (isDebug) { StringBuffer logMessageBuffer = new StringBuffer(128) .append("Sending mail to ") .append(mail.getRecipients()) .append(" via ") .append(gatewayServer); log(logMessageBuffer.toString()); } //Set it to try to deliver (in a separate thread) immediately (triggered by storage) outgoing.store(mail); } mail.setState(Mail.GHOST); } // Need to synchronize to get object monitor for notifyAll() public synchronized void destroy() { //Mark flag so threads from this mailet stop themselves destroyed = true; //Wake up all threads from waiting for an accept for (Iterator i = deliveryThreads.iterator(); i.hasNext(); ) { Thread t = (Thread)i.next(); t.interrupt(); } notifyAll(); } /** * Handles checking the outgoing spool for new mail and delivering them if * there are any */ public void run() { /* TODO: CHANGE ME!!! The problem is that we need to wait for James to * finish initializing. We expect the HELLO_NAME to be put into * the MailetContext, but in the current configuration we get * started before the SMTP Server, which establishes the value. * Since there is no contractual guarantee that there will be a * HELLO_NAME value, we can't just wait for it. As a temporary * measure, I'm inserting this philosophically unsatisfactory * fix. */ long stop = System.currentTimeMillis() + 60000; while ((getMailetContext().getAttribute(Constants.HELLO_NAME) == null) && stop > System.currentTimeMillis()) { try { Thread.sleep(1000); } catch (Exception ignored) {} // wait for James to finish initializing } //Checks the pool and delivers a mail message Properties props = new Properties(); //Not needed for production environment props.put("mail.debug", "false"); // Reactivated: javamail 1.3.2 should no more have problems with "250 OK" // messages (WAS "false": Prevents problems encountered with 250 OK Messages) props.put("mail.smtp.ehlo", "true"); // By setting this property to true the transport is allowed to // send 8 bit data to the server (if it supports the 8bitmime extension). // 2006/03/01 reverted to false because of a javamail bug converting to 8bit // messages created by an inputstream. props.setProperty("mail.smtp.allow8bitmime", "false"); //Sets timeout on going connections props.put("mail.smtp.timeout", smtpTimeout + ""); props.put("mail.smtp.connectiontimeout", connectionTimeout + ""); props.put("mail.smtp.sendpartial",String.valueOf(sendPartial)); //Set the hostname we'll use as this server if (getMailetContext().getAttribute(Constants.HELLO_NAME) != null) { props.put("mail.smtp.localhost", getMailetContext().getAttribute(Constants.HELLO_NAME)); } else { String defaultDomain = (String) getMailetContext().getAttribute(Constants.DEFAULT_DOMAIN); if (defaultDomain != null) { props.put("mail.smtp.localhost", defaultDomain); } } if (isBindUsed) { // undocumented JavaMail 1.2 feature, smtp transport will use // our socket factory, which will also set the local address props.put("mail.smtp.socketFactory.class", "org.apache.james.transport.mailets.RemoteDeliverySocketFactory"); // Don't fallback to the standard socket factory on error, do throw an exception props.put("mail.smtp.socketFactory.fallback", "false"); } if (authUser != null) { props.put("mail.smtp.auth","true"); } props.putAll(defprops); Session session = Session.getInstance(props, null); try { while (!Thread.interrupted() && !destroyed) { try { Mail mail = (Mail)outgoing.accept(delayFilter); String key = mail.getName();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -