PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/james-2.2.0/src/java/org/apache/james/fetchmail/MessageProcessor.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 1494 lines | 807 code | 148 blank | 539 comment | 105 complexity | dc53f165ce25e96fd530c7fe881a4409 MD5 | raw file
  1. /***********************************************************************
  2. * Copyright (c) 2003-2004 The Apache Software Foundation. *
  3. * All rights reserved. *
  4. * ------------------------------------------------------------------- *
  5. * Licensed under the Apache License, Version 2.0 (the "License"); you *
  6. * may not use this file except in compliance with the License. You *
  7. * may obtain a copy of the License at: *
  8. * *
  9. * http://www.apache.org/licenses/LICENSE-2.0 *
  10. * *
  11. * Unless required by applicable law or agreed to in writing, software *
  12. * distributed under the License is distributed on an "AS IS" BASIS, *
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
  14. * implied. See the License for the specific language governing *
  15. * permissions and limitations under the License. *
  16. ***********************************************************************/
  17. package org.apache.james.fetchmail;
  18. import java.io.InputStream;
  19. import java.net.InetAddress;
  20. import java.net.UnknownHostException;
  21. import java.util.ArrayList;
  22. import java.util.Collection;
  23. import java.util.Enumeration;
  24. import java.util.Iterator;
  25. import java.util.StringTokenizer;
  26. import javax.mail.Address;
  27. import javax.mail.Flags;
  28. import javax.mail.Folder;
  29. import javax.mail.MessagingException;
  30. import javax.mail.Session;
  31. import javax.mail.internet.InternetAddress;
  32. import javax.mail.internet.InternetHeaders;
  33. import javax.mail.internet.MimeMessage;
  34. import javax.mail.internet.ParseException;
  35. import org.apache.james.core.MailImpl;
  36. import org.apache.james.util.RFC2822Headers;
  37. import org.apache.mailet.Mail;
  38. import org.apache.mailet.MailAddress;
  39. /**
  40. * <p>Class <code>MessageProcessor</code> handles the delivery of
  41. * <code>MimeMessages</code> to the James input spool.</p>
  42. *
  43. * <p>Messages written to the input spool always have the following Mail
  44. * Attributes set:</p>
  45. * <dl>
  46. * <dt>org.apache.james.fetchmail.taskName (java.lang.String)</dt>
  47. * <dd>The name of the fetch task that processed the message</dd>
  48. * <dt>org.apache.james.fetchmail.folderName (java.lang.String)</dt>
  49. * <dd>The name of the folder from which the message was fetched</dd>
  50. * </dl>
  51. *
  52. * <p>Messages written to the input spool have the following Mail Attributes
  53. * set if the corresponding condition is satisfied:
  54. * <dl>
  55. * <dt>org.apache.james.fetchmail.isBlacklistedRecipient</dt>
  56. * <dd>The recipient is in the configured blacklist</dd>
  57. * <dt>org.apache.james.fetchmail.isMaxMessageSizeExceeded (java.lang.String)</dt>
  58. * <dd>The message size exceeds the configured limit. An empty message is
  59. * written to the input spool. The Mail Attribute value is a String
  60. * representing the size of the original message in bytes.</dd>
  61. * <dt>org.apache.james.fetchmail.isRecipientNotFound</dt>
  62. * <dd>The recipient could not be found. Delivery is to the configured recipient.
  63. * See the discussion of delivery to a sole intended recipient below.</dd>
  64. * <dt>org.apache.james.fetchmail.isRemoteRecievedHeaderInvalid</dt>
  65. * <dd>The Receieved header at the index specified by parameter
  66. * <code>remoteReceivedHeaderIndex</code> is invalid.</dd>
  67. * <dt>org.apache.james.fetchmail.isRemoteRecipient</dt>
  68. * <dd>The recipient is on a remote host</dd>
  69. * <dt>org.apache.james.fetchmail.isUserUndefined</dt>
  70. * <dd>The recipient is on a localhost but not defined to James</dd>
  71. * </dl>
  72. *
  73. * <p>Configuration settings -
  74. * see <code>org.apache.james.fetchmail.ParsedConfiguration</code>
  75. * - control the messages that are written to the James input spool, those that
  76. * are rejected and what happens to messages that are rejected.</p>
  77. *
  78. * <p>Rejection processing is based on the following filters:</p>
  79. * <dl>
  80. * <dt>RejectRemoteRecipient</dt>
  81. * <dd>Rejects recipients on remote hosts</dd>
  82. * <dt>RejectBlacklistedRecipient</dt>
  83. * <dd>Rejects recipients configured in a blacklist</dd>
  84. * <dt>RejectUserUndefined</dt>
  85. * <dd>Rejects recipients on local hosts who are not defined as James users</dd>
  86. * <dt>RejectRecipientNotFound</dt>
  87. * <dd>See the discussion of delivery to a sole intended recipient below</dd>
  88. * <dt>RejectMaxMessageSizeExceeded</dt>
  89. * <dd>Rejects messages whose size exceeds the configured limit</dd>
  90. * <dt>RejectRemoteReceievedHeaderInvalid</dt>
  91. * <dd>Rejects messages whose Received header is invalid.</dd>
  92. * </dl>
  93. *
  94. * <p>Rejection processing is intentionally limited to managing the status of the
  95. * messages that are rejected on the server from which they were fetched. View
  96. * it as a simple automation of the manual processing an end-user would perform
  97. * through a mail client. Messages may be marked as seen or be deleted.</p>
  98. *
  99. * <p>Further processing can be achieved by configuring to disable rejection for
  100. * one or more filters. This enables Messages that would have been rejected to
  101. * be written to the James input spool. The conditional Mail Attributes
  102. * described above identify the filter states. The Matcher/Mailet chain can
  103. * then be used to perform any further processing required, such as notifying
  104. * the Postmaster and/or sender, marking the message for error processing, etc.</p>
  105. *
  106. * <p>Note that in the case of a message exceeding the message size limit, the
  107. * message that is written to the input spool has no content. This enables
  108. * configuration of a mailet notifying the sender that their mail has not been
  109. * delivered due to its size while maintaining the purpose of the filter which is
  110. * to avoid injecting excessively large messages into the input spool.</p>
  111. *
  112. * <p>Delivery is to a sole intended recipient. The recipient is determined in the
  113. * following manner:</p>
  114. *
  115. * <ol>
  116. * <li>If isIgnoreIntendedRecipient(), use the configured recipient</li>
  117. * <li>If the Envelope contains a for: stanza, use the recipient in the stanza</li>
  118. * <li>If the Message has a sole intended recipient, use this recipient</li>
  119. * <li>If not rejectRecipientNotFound(), use the configured recipient</li>
  120. * </ol>
  121. *
  122. * <p>If a recipient cannot be determined after these steps, the message is
  123. * rejected.</p>
  124. *
  125. * <p>Every delivered message CURRENTLY has an "X-fetched-from" header added
  126. * containing the name of the fetch task. Its primary uses are to detect bouncing
  127. * mail and provide backwards compatibility with the fetchPop task that inserted
  128. * this header to enable injected messages to be detected in the Matcher/Mailet
  129. * chain. This header is DEPRECATED and WILL BE REMOVED in a future version of
  130. * fetchmail. Use the Mail Attribute <code>org.apache.james.fetchmail.taskName</code>
  131. * instead.
  132. *
  133. * <p><code>MessageProcessor</code> is as agnostic as it can be about the format
  134. * and contents of the messages it delivers. There are no RFCs that govern its
  135. * behavior. The most releveant RFCs relate to the exchange of messages between
  136. * MTA servers, but not POP3 or IMAP servers which are normally end-point
  137. * servers and not expected to re-inject mail into MTAs. None the less, the
  138. * intent is to conform to the 'spirit' of the RFCs.
  139. * <code>MessageProcessor</code> relies on the MTA (James in this
  140. * implementation) to manage and validate the injected mail just as it would
  141. * when receiving mail from an upstream MTA.</p>
  142. *
  143. * <p>The only correction applied by <code>MessageProcessor</code> is to correct a
  144. * partial originator address. If the originator address has a valid user part
  145. * but no domain part, a domain part is added. The added domain is either the
  146. * default domain specified in the configuration, or if not specified, the
  147. * fully qualified name of the machine on which the fetch task is running.</p>
  148. *
  149. * <p>The status of messages on the server from which they were fetched that
  150. * cannot be injected into the input spool due to non-correctable errors is
  151. * determined by the undeliverable configuration options.</p>
  152. *
  153. * <p>Creation Date: 27-May-03</p>
  154. *
  155. */
  156. public class MessageProcessor extends ProcessorAbstract
  157. {
  158. private MimeMessage fieldMessageIn;
  159. /**
  160. * Recipient cannot be found
  161. */
  162. private boolean fieldRecipientNotFound = false;
  163. /**
  164. * Recipient is a local user on a local host
  165. */
  166. private boolean fieldRemoteRecipient = true;
  167. /**
  168. * The mail's Received header at index remoteReceivedHeaderIndex is invalid.
  169. */
  170. private Boolean fieldRemoteReceivedHeaderInvalid;
  171. /**
  172. * Recipient is not a local user
  173. */
  174. private boolean fieldUserUndefined = false;
  175. /**
  176. * The Maximum Message has been exceeded
  177. */
  178. private Boolean fieldMaxMessageSizeExceeded;
  179. /**
  180. * Field names for an RFC2822 compliant RECEIVED Header
  181. */
  182. static final private String fieldRFC2822RECEIVEDHeaderFields =
  183. "from by via with id for ;";
  184. /**
  185. * Recipient is blacklisted
  186. */
  187. private boolean fieldBlacklistedRecipient = false;
  188. /**
  189. * The RFC2822 compliant "Received : from" domain
  190. */
  191. private String fieldRemoteDomain;
  192. /**
  193. * The remote address derived from the remote domain
  194. */
  195. private String fieldRemoteAddress;
  196. /**
  197. * The remote host name derived from the remote domain
  198. */
  199. private String fieldRemoteHostName;
  200. /**
  201. * Constructor for MessageProcessor.
  202. *
  203. * @param account
  204. */
  205. private MessageProcessor(Account account)
  206. {
  207. super(account);
  208. }
  209. /**
  210. * Constructor for MessageProcessor.
  211. *
  212. * @param messageIn
  213. * @param account
  214. */
  215. MessageProcessor(
  216. MimeMessage messageIn,
  217. Account account)
  218. {
  219. this(account);
  220. setMessageIn(messageIn);
  221. }
  222. /**
  223. * Method process attempts to deliver a fetched message.
  224. *
  225. * @see org.apache.james.fetchmail.ProcessorAbstract#process()
  226. */
  227. public void process() throws MessagingException
  228. {
  229. // Log delivery attempt
  230. if (getLogger().isDebugEnabled())
  231. {
  232. StringBuffer logMessageBuffer =
  233. new StringBuffer("Attempting delivery of message with id. ");
  234. logMessageBuffer.append(getMessageIn().getMessageID());
  235. getLogger().debug(logMessageBuffer.toString());
  236. }
  237. // Determine the intended recipient
  238. MailAddress intendedRecipient = getIntendedRecipient();
  239. setRecipientNotFound(null == intendedRecipient);
  240. if (isRecipientNotFound())
  241. {
  242. if (isDeferRecipientNotFound())
  243. {
  244. String messageID = getMessageIn().getMessageID();
  245. if (!getDeferredRecipientNotFoundMessageIDs()
  246. .contains(messageID))
  247. {
  248. getDeferredRecipientNotFoundMessageIDs().add(messageID);
  249. if (getLogger().isDebugEnabled())
  250. {
  251. StringBuffer messageBuffer =
  252. new StringBuffer("Deferred processing of message for which the intended recipient could not be found. Message ID: ");
  253. messageBuffer.append(messageID);
  254. getLogger().debug(messageBuffer.toString());
  255. }
  256. return;
  257. }
  258. else
  259. {
  260. getDeferredRecipientNotFoundMessageIDs().remove(messageID);
  261. if (getLogger().isDebugEnabled())
  262. {
  263. StringBuffer messageBuffer =
  264. new StringBuffer("Processing deferred message for which the intended recipient could not be found. Message ID: ");
  265. messageBuffer.append(messageID);
  266. getLogger().debug(messageBuffer.toString());
  267. }
  268. }
  269. }
  270. if (isRejectRecipientNotFound())
  271. {
  272. rejectRecipientNotFound();
  273. return;
  274. }
  275. intendedRecipient = getRecipient();
  276. StringBuffer messageBuffer =
  277. new StringBuffer("Intended recipient not found. Using configured recipient as new envelope recipient - ");
  278. messageBuffer.append(intendedRecipient);
  279. messageBuffer.append('.');
  280. logStatusInfo(messageBuffer.toString());
  281. }
  282. // Set the filter states
  283. setBlacklistedRecipient(isBlacklistedRecipient(intendedRecipient));
  284. setRemoteRecipient(!isLocalServer(intendedRecipient));
  285. setUserUndefined(!isLocalRecipient(intendedRecipient));
  286. // Apply the filters. Return if rejected
  287. if (isRejectBlacklisted() && isBlacklistedRecipient())
  288. {
  289. rejectBlacklistedRecipient(intendedRecipient);
  290. return;
  291. }
  292. if (isRejectRemoteRecipient() && isRemoteRecipient())
  293. {
  294. rejectRemoteRecipient(intendedRecipient);
  295. return;
  296. }
  297. if (isRejectUserUndefined() && isUserUndefined())
  298. {
  299. rejectUserUndefined(intendedRecipient);
  300. return;
  301. }
  302. if (isRejectMaxMessageSizeExceeded()
  303. && isMaxMessageSizeExceeded().booleanValue())
  304. {
  305. rejectMaxMessageSizeExceeded(getMessageIn().getSize());
  306. return;
  307. }
  308. if (isRejectRemoteReceivedHeaderInvalid()
  309. && isRemoteReceivedHeaderInvalid().booleanValue())
  310. {
  311. rejectRemoteReceivedHeaderInvalid();
  312. return;
  313. }
  314. // Create the mail
  315. // If any of the mail addresses are malformed, we will get a
  316. // ParseException.
  317. // If the IP address and host name for the remote domain cannot
  318. // be found, we will get an UnknownHostException.
  319. // In both cases, we log the problem and
  320. // return. The message disposition is defined by the
  321. // <undeliverable> attributes.
  322. Mail mail = null;
  323. try
  324. {
  325. mail = createMail(createMessage(), intendedRecipient);
  326. }
  327. catch (ParseException ex)
  328. {
  329. handleParseException(ex);
  330. return;
  331. }
  332. catch (UnknownHostException ex)
  333. {
  334. handleUnknownHostException(ex);
  335. return;
  336. }
  337. addMailAttributes(mail);
  338. addErrorMessages(mail);
  339. // If this mail is bouncing move it to the ERROR repository
  340. if (isBouncing())
  341. {
  342. handleBouncing(mail);
  343. return;
  344. }
  345. // OK, lets send that mail!
  346. sendMail(mail);
  347. }
  348. /**
  349. * Method rejectRemoteRecipient.
  350. * @param recipient
  351. * @throws MessagingException
  352. */
  353. protected void rejectRemoteRecipient(MailAddress recipient)
  354. throws MessagingException
  355. {
  356. // Update the flags of the received message
  357. if (!isLeaveRemoteRecipient())
  358. setMessageDeleted();
  359. if (isMarkRemoteRecipientSeen())
  360. setMessageSeen();
  361. StringBuffer messageBuffer =
  362. new StringBuffer("Rejected mail intended for remote recipient: ");
  363. messageBuffer.append(recipient);
  364. messageBuffer.append('.');
  365. logStatusInfo(messageBuffer.toString());
  366. return;
  367. }
  368. /**
  369. * Method rejectBlacklistedRecipient.
  370. * @param recipient
  371. * @throws MessagingException
  372. */
  373. protected void rejectBlacklistedRecipient(MailAddress recipient)
  374. throws MessagingException
  375. {
  376. // Update the flags of the received message
  377. if (!isLeaveBlacklisted())
  378. setMessageDeleted();
  379. if (isMarkBlacklistedSeen())
  380. setMessageSeen();
  381. StringBuffer messageBuffer =
  382. new StringBuffer("Rejected mail intended for blacklisted recipient: ");
  383. messageBuffer.append(recipient);
  384. messageBuffer.append('.');
  385. logStatusInfo(messageBuffer.toString());
  386. return;
  387. }
  388. /**
  389. * Method rejectRecipientNotFound.
  390. * @throws MessagingException
  391. */
  392. protected void rejectRecipientNotFound() throws MessagingException
  393. {
  394. // Update the flags of the received message
  395. if (!isLeaveRecipientNotFound())
  396. setMessageDeleted();
  397. if (isMarkRecipientNotFoundSeen())
  398. setMessageSeen();
  399. StringBuffer messageBuffer =
  400. new StringBuffer("Rejected mail for which a sole intended recipient could not be found.");
  401. messageBuffer.append(" Recipients: ");
  402. Address[] allRecipients = getMessageIn().getAllRecipients();
  403. for (int i = 0; i < allRecipients.length; i++)
  404. {
  405. messageBuffer.append(allRecipients[i]);
  406. messageBuffer.append(' ');
  407. }
  408. messageBuffer.append('.');
  409. logStatusInfo(messageBuffer.toString());
  410. return;
  411. }
  412. /**
  413. * Method rejectUserUndefined.
  414. * @param recipient
  415. * @throws MessagingException
  416. */
  417. protected void rejectUserUndefined(MailAddress recipient)
  418. throws MessagingException
  419. {
  420. // Update the flags of the received message
  421. if (!isLeaveUserUndefined())
  422. setMessageDeleted();
  423. if (isMarkUserUndefinedSeen())
  424. setMessageSeen();
  425. StringBuffer messageBuffer =
  426. new StringBuffer("Rejected mail intended for undefined user: ");
  427. messageBuffer.append(recipient);
  428. messageBuffer.append('.');
  429. logStatusInfo(messageBuffer.toString());
  430. return;
  431. }
  432. /**
  433. * Method rejectMaxMessageSizeExceeded.
  434. * @param message size
  435. * @throws MessagingException
  436. */
  437. protected void rejectMaxMessageSizeExceeded(int messageSize)
  438. throws MessagingException
  439. {
  440. // Update the flags of the received message
  441. if (!isLeaveMaxMessageSizeExceeded())
  442. setMessageDeleted();
  443. if (isMarkMaxMessageSizeExceededSeen())
  444. setMessageSeen();
  445. StringBuffer messageBuffer =
  446. new StringBuffer("Rejected mail exceeding message size limit. Message size: ");
  447. messageBuffer.append(messageSize/1024);
  448. messageBuffer.append("KB.");
  449. logStatusInfo(messageBuffer.toString());
  450. return;
  451. }
  452. /**
  453. * Method rejectRemoteReceivedHeaderInvalid.
  454. * @throws MessagingException
  455. */
  456. protected void rejectRemoteReceivedHeaderInvalid()
  457. throws MessagingException
  458. {
  459. // Update the flags of the received message
  460. if (!isLeaveRemoteReceivedHeaderInvalid())
  461. setMessageDeleted();
  462. if (isMarkRemoteReceivedHeaderInvalidSeen())
  463. setMessageSeen();
  464. StringBuffer messageBuffer =
  465. new StringBuffer("Rejected mail with an invalid Received: header at index ");
  466. messageBuffer.append(getRemoteReceivedHeaderIndex());
  467. messageBuffer.append(".");
  468. logStatusInfo(messageBuffer.toString());
  469. return;
  470. }
  471. /**
  472. * <p>Method createMessage answers a new <code>MimeMessage</code> from the
  473. * fetched message.</p>
  474. *
  475. * <p>If the maximum message size is exceeded, an empty message is created,
  476. * else the new message is a copy of the received message.</p>
  477. *
  478. * @return MimeMessage
  479. * @throws MessagingException
  480. */
  481. protected MimeMessage createMessage() throws MessagingException
  482. {
  483. // Create a new messsage from the received message
  484. MimeMessage messageOut = null;
  485. if (isMaxMessageSizeExceeded().booleanValue())
  486. messageOut = createEmptyMessage();
  487. else
  488. messageOut = new MimeMessage(getMessageIn());
  489. // set the X-fetched headers
  490. // Note this is still required to detect bouncing mail and
  491. // for backwards compatibility with fetchPop
  492. messageOut.addHeader("X-fetched-from", getFetchTaskName());
  493. return messageOut;
  494. }
  495. /**
  496. * Method createEmptyMessage answers a new
  497. * <code>MimeMessage</code> from the fetched message with the message
  498. * contents removed.
  499. *
  500. * @return MimeMessage
  501. * @throws MessagingException
  502. */
  503. protected MimeMessage createEmptyMessage()
  504. throws MessagingException
  505. {
  506. // Create an empty messsage
  507. MimeMessage messageOut = new MimeMessage(getSession());
  508. // Propogate the headers and subject
  509. Enumeration headersInEnum = getMessageIn().getAllHeaderLines();
  510. while (headersInEnum.hasMoreElements())
  511. messageOut.addHeaderLine((String) headersInEnum.nextElement());
  512. messageOut.setSubject(getMessageIn().getSubject());
  513. // Add empty text
  514. messageOut.setText("");
  515. // Save
  516. messageOut.saveChanges();
  517. return messageOut;
  518. }
  519. /**
  520. * Method createMail creates a new <code>Mail</code>.
  521. *
  522. * @param message
  523. * @param recipient
  524. * @return Mail
  525. * @throws MessagingException
  526. */
  527. protected Mail createMail(MimeMessage message, MailAddress recipient)
  528. throws MessagingException, UnknownHostException
  529. {
  530. Collection recipients = new ArrayList(1);
  531. recipients.add(recipient);
  532. MailImpl mail =
  533. new MailImpl(getServer().getId(), getSender(), recipients, message);
  534. // Ensure the mail is created with non-null remote host name and address,
  535. // otherwise the Mailet chain may go splat!
  536. if (getRemoteAddress() == null || getRemoteHostName() == null)
  537. {
  538. mail.setRemoteAddr("127.0.0.1");
  539. mail.setRemoteHost("localhost");
  540. }
  541. else
  542. {
  543. mail.setRemoteAddr(getRemoteAddress());
  544. mail.setRemoteHost(getRemoteHostName());
  545. }
  546. if (getLogger().isDebugEnabled())
  547. {
  548. StringBuffer messageBuffer =
  549. new StringBuffer("Created mail with name: ");
  550. messageBuffer.append(mail.getName());
  551. messageBuffer.append(", sender: ");
  552. messageBuffer.append(mail.getSender());
  553. messageBuffer.append(", recipients: ");
  554. Iterator recipientIterator = mail.getRecipients().iterator();
  555. while (recipientIterator.hasNext())
  556. {
  557. messageBuffer.append(recipientIterator.next());
  558. messageBuffer.append(' ');
  559. }
  560. messageBuffer.append(", remote address: ");
  561. messageBuffer.append(mail.getRemoteAddr());
  562. messageBuffer.append(", remote host name: ");
  563. messageBuffer.append(mail.getRemoteHost());
  564. messageBuffer.append('.');
  565. getLogger().debug(messageBuffer.toString());
  566. }
  567. return mail;
  568. }
  569. /**
  570. * Method getSender answers a <code>MailAddress</code> for the sender.
  571. *
  572. * @return MailAddress
  573. * @throws MessagingException
  574. */
  575. protected MailAddress getSender() throws MessagingException
  576. {
  577. String from = "FETCHMAIL-SERVICE";
  578. try {
  579. from = ((InternetAddress) getMessageIn().getFrom()[0]).getAddress().trim();
  580. }
  581. catch (Exception _) {
  582. getLogger().info("Could not identify sender -- using default value");
  583. }
  584. InternetAddress internetAddress = null;
  585. // Check for domain part, add default if missing
  586. if (from.indexOf('@') < 0)
  587. {
  588. StringBuffer fromBuffer = new StringBuffer(from);
  589. fromBuffer.append('@');
  590. fromBuffer.append(getDefaultDomainName());
  591. internetAddress = new InternetAddress(fromBuffer.toString());
  592. }
  593. else
  594. internetAddress = new InternetAddress(from);
  595. return new MailAddress(internetAddress);
  596. }
  597. /**
  598. * <p>Method computeRemoteDomain answers a <code>String</code> that is the
  599. * RFC2822 compliant "Received : from" domain extracted from the message
  600. * being processed.</p>
  601. *
  602. * <p>Normally this is the domain that sent the message to the host for the
  603. * message store as reported by the second "received" header. The index of
  604. * the header to use is specified by the configuration parameter
  605. * <code>RemoteReceivedHeaderIndex</code>. If a header at this index does
  606. * not exist, the domain of the successively closer "received" headers
  607. * is tried until they are exhausted, then "localhost" is used.</p>
  608. *
  609. * @return String
  610. */
  611. protected String computeRemoteDomain() throws MessagingException
  612. {
  613. StringBuffer domainBuffer = new StringBuffer();
  614. String[] headers = null;
  615. if (getRemoteReceivedHeaderIndex() > -1)
  616. getMessageIn().getHeader(RFC2822Headers.RECEIVED);
  617. if (null != headers)
  618. {
  619. // If there are RECEIVED headers and the index to begin at is greater
  620. // than -1, try and extract the domain
  621. if (headers.length > 0)
  622. {
  623. final String headerTokens = " \n\r";
  624. // Search the headers for a domain
  625. for (int headerIndex =
  626. headers.length > getRemoteReceivedHeaderIndex()
  627. ? getRemoteReceivedHeaderIndex()
  628. : headers.length - 1;
  629. headerIndex >= 0 && domainBuffer.length() == 0;
  630. headerIndex--)
  631. {
  632. // Find the "from" token
  633. StringTokenizer tokenizer =
  634. new StringTokenizer(headers[headerIndex], headerTokens);
  635. boolean inFrom = false;
  636. while (!inFrom && tokenizer.hasMoreTokens())
  637. inFrom = tokenizer.nextToken().equals("from");
  638. // Add subsequent tokens to the domain buffer until another
  639. // field is encountered or there are no more tokens
  640. while (inFrom && tokenizer.hasMoreTokens())
  641. {
  642. String token = tokenizer.nextToken();
  643. if (inFrom =
  644. getRFC2822RECEIVEDHeaderFields().indexOf(token)
  645. == -1)
  646. {
  647. domainBuffer.append(token);
  648. domainBuffer.append(' ');
  649. }
  650. }
  651. }
  652. }
  653. }
  654. // Default is "localhost"
  655. if (domainBuffer.length() == 0)
  656. domainBuffer.append("localhost");
  657. return domainBuffer.toString().trim();
  658. }
  659. /**
  660. * Method handleBouncing sets the Mail state to ERROR and delete from
  661. * the message store.
  662. *
  663. * @param mail
  664. */
  665. protected void handleBouncing(Mail mail) throws MessagingException
  666. {
  667. mail.setState(Mail.ERROR);
  668. setMessageDeleted();
  669. mail.setErrorMessage(
  670. "This mail from FetchMail task "
  671. + getFetchTaskName()
  672. + " seems to be bouncing!");
  673. logStatusError("Message is bouncing! Deleted from message store and moved to the Error repository.");
  674. }
  675. /**
  676. * Method handleParseException.
  677. * @param ex
  678. * @throws MessagingException
  679. */
  680. protected void handleParseException(ParseException ex)
  681. throws MessagingException
  682. {
  683. // Update the flags of the received message
  684. if (!isLeaveUndeliverable())
  685. setMessageDeleted();
  686. if (isMarkUndeliverableSeen())
  687. setMessageSeen();
  688. logStatusWarn("Message could not be delivered due to an error parsing a mail address.");
  689. if (getLogger().isDebugEnabled())
  690. {
  691. StringBuffer messageBuffer =
  692. new StringBuffer("UNDELIVERABLE Message ID: ");
  693. messageBuffer.append(getMessageIn().getMessageID());
  694. getLogger().debug(messageBuffer.toString(), ex);
  695. }
  696. }
  697. /**
  698. * Method handleUnknownHostException.
  699. * @param ex
  700. * @throws MessagingException
  701. */
  702. protected void handleUnknownHostException(UnknownHostException ex)
  703. throws MessagingException
  704. {
  705. // Update the flags of the received message
  706. if (!isLeaveUndeliverable())
  707. setMessageDeleted();
  708. if (isMarkUndeliverableSeen())
  709. setMessageSeen();
  710. logStatusWarn("Message could not be delivered due to an error determining the remote domain.");
  711. if (getLogger().isDebugEnabled())
  712. {
  713. StringBuffer messageBuffer =
  714. new StringBuffer("UNDELIVERABLE Message ID: ");
  715. messageBuffer.append(getMessageIn().getMessageID());
  716. getLogger().debug(messageBuffer.toString(), ex);
  717. }
  718. }
  719. /**
  720. * Method isLocalRecipient.
  721. * @param recipient
  722. * @return boolean
  723. */
  724. protected boolean isLocalRecipient(MailAddress recipient)
  725. {
  726. return isLocalUser(recipient) && isLocalServer(recipient);
  727. }
  728. /**
  729. * Method isLocalServer.
  730. * @param recipient
  731. * @return boolean
  732. */
  733. protected boolean isLocalServer(MailAddress recipient)
  734. {
  735. return getServer().isLocalServer(recipient.getHost());
  736. }
  737. /**
  738. * Method isLocalUser.
  739. * @param recipient
  740. * @return boolean
  741. */
  742. protected boolean isLocalUser(MailAddress recipient)
  743. {
  744. return getLocalUsers().containsCaseInsensitive(recipient.getUser());
  745. }
  746. /**
  747. * Method isBlacklistedRecipient.
  748. * @param recipient
  749. * @return boolean
  750. */
  751. protected boolean isBlacklistedRecipient(MailAddress recipient)
  752. {
  753. return getBlacklist().contains(recipient);
  754. }
  755. /**
  756. * Check if this mail has been bouncing by counting the X-fetched-from
  757. * headers for this task
  758. *
  759. * @return boolean
  760. */
  761. protected boolean isBouncing() throws MessagingException
  762. {
  763. Enumeration enum =
  764. getMessageIn().getMatchingHeaderLines(
  765. new String[] { "X-fetched-from" });
  766. int count = 0;
  767. while (enum.hasMoreElements())
  768. {
  769. String header = (String) enum.nextElement();
  770. if (header.equals(getFetchTaskName()))
  771. count++;
  772. }
  773. return count >= 3;
  774. }
  775. /**
  776. * Method sendMail.
  777. * @param mail
  778. * @throws MessagingException
  779. */
  780. protected void sendMail(Mail mail) throws MessagingException
  781. {
  782. // send the mail
  783. getServer().sendMail(mail);
  784. // Update the flags of the received message
  785. if (!isLeave())
  786. setMessageDeleted();
  787. if (isMarkSeen())
  788. setMessageSeen();
  789. // Log the status
  790. StringBuffer messageBuffer =
  791. new StringBuffer("Spooled message to recipients: ");
  792. Iterator recipientIterator = mail.getRecipients().iterator();
  793. while (recipientIterator.hasNext())
  794. {
  795. messageBuffer.append(recipientIterator.next());
  796. messageBuffer.append(' ');
  797. }
  798. messageBuffer.append('.');
  799. logStatusInfo(messageBuffer.toString());
  800. }
  801. /**
  802. * Method getEnvelopeRecipient answers the recipient if found else null.
  803. *
  804. * Try and parse the "for" parameter from a Received header
  805. * Maybe not the most accurate parsing in the world but it should do
  806. * I opted not to use ORO (maybe I should have)
  807. *
  808. * @param msg
  809. * @return String
  810. */
  811. protected String getEnvelopeRecipient(MimeMessage msg) throws MessagingException
  812. {
  813. try
  814. {
  815. Enumeration enum =
  816. msg.getMatchingHeaderLines(new String[] { "Received" });
  817. while (enum.hasMoreElements())
  818. {
  819. String received = (String) enum.nextElement();
  820. int nextSearchAt = 0;
  821. int i = 0;
  822. int start = 0;
  823. int end = 0;
  824. boolean hasBracket = false;
  825. boolean usableAddress = false;
  826. while (!usableAddress && (i != -1))
  827. {
  828. hasBracket = false;
  829. i = received.indexOf("for ", nextSearchAt);
  830. if (i > 0)
  831. {
  832. start = i + 4;
  833. end = 0;
  834. nextSearchAt = start;
  835. for (int c = start; c < received.length(); c++)
  836. {
  837. char ch = received.charAt(c);
  838. switch (ch)
  839. {
  840. case '<' :
  841. hasBracket = true;
  842. continue;
  843. case '@' :
  844. usableAddress = true;
  845. continue;
  846. case ' ' :
  847. end = c;
  848. break;
  849. case ';' :
  850. end = c;
  851. break;
  852. }
  853. if (end > 0)
  854. break;
  855. }
  856. }
  857. }
  858. if (usableAddress)
  859. {
  860. // lets try and grab the email address
  861. String mailFor = received.substring(start, end);
  862. // strip the <> around the address if there are any
  863. if (mailFor.startsWith("<") && mailFor.endsWith(">"))
  864. mailFor = mailFor.substring(1, (mailFor.length() - 1));
  865. return mailFor;
  866. }
  867. }
  868. }
  869. catch (MessagingException me)
  870. {
  871. logStatusWarn("No Received headers found.");
  872. }
  873. return null;
  874. }
  875. /**
  876. * Method getIntendedRecipient answers the sole intended recipient else null.
  877. *
  878. * @return MailAddress
  879. * @throws MessagingException
  880. */
  881. protected MailAddress getIntendedRecipient() throws MessagingException
  882. {
  883. // If the original recipient should be ignored, answer the
  884. // hard-coded recipient
  885. if (isIgnoreRecipientHeader())
  886. {
  887. StringBuffer messageBuffer =
  888. new StringBuffer("Ignoring recipient header. Using configured recipient as new envelope recipient: ");
  889. messageBuffer.append(getRecipient());
  890. messageBuffer.append('.');
  891. logStatusInfo(messageBuffer.toString());
  892. return getRecipient();
  893. }
  894. // If we can determine who the message was received for, answer
  895. // the target recipient
  896. String targetRecipient = getEnvelopeRecipient(getMessageIn());
  897. if (targetRecipient != null)
  898. {
  899. MailAddress recipient = new MailAddress(targetRecipient);
  900. StringBuffer messageBuffer =
  901. new StringBuffer("Using original envelope recipient as new envelope recipient: ");
  902. messageBuffer.append(recipient);
  903. messageBuffer.append('.');
  904. logStatusInfo(messageBuffer.toString());
  905. return recipient;
  906. }
  907. // If we can determine the intended recipient from all of the recipients,
  908. // answer the intended recipient. This requires that there is exactly one
  909. // recipient answered by getAllRecipients(), which examines the TO: CC: and
  910. // BCC: headers
  911. Address[] allRecipients = getMessageIn().getAllRecipients();
  912. if (allRecipients.length == 1)
  913. {
  914. MailAddress recipient =
  915. new MailAddress((InternetAddress) allRecipients[0]);
  916. StringBuffer messageBuffer =
  917. new StringBuffer("Using sole recipient header address as new envelope recipient: ");
  918. messageBuffer.append(recipient);
  919. messageBuffer.append('.');
  920. logStatusInfo(messageBuffer.toString());
  921. return recipient;
  922. }
  923. return null;
  924. }
  925. /**
  926. * Returns the messageIn.
  927. * @return MimeMessage
  928. */
  929. protected MimeMessage getMessageIn()
  930. {
  931. return fieldMessageIn;
  932. }
  933. /**
  934. * Sets the messageIn.
  935. * @param messageIn The messageIn to set
  936. */
  937. protected void setMessageIn(MimeMessage messageIn)
  938. {
  939. fieldMessageIn = messageIn;
  940. }
  941. /**
  942. * Returns the localRecipient.
  943. * @return boolean
  944. */
  945. protected boolean isRemoteRecipient()
  946. {
  947. return fieldRemoteRecipient;
  948. }
  949. /**
  950. * Returns <code>boolean</code> indicating if the message to be delivered
  951. * was unprocessed in a previous delivery attempt.
  952. * @return boolean
  953. */
  954. protected boolean isPreviouslyUnprocessed()
  955. {
  956. return true;
  957. }
  958. /**
  959. * Log the status of the current message as INFO.
  960. * @param detailMsg
  961. */
  962. protected void logStatusInfo(String detailMsg) throws MessagingException
  963. {
  964. getLogger().info(getStatusReport(detailMsg).toString());
  965. }
  966. /**
  967. * Log the status the current message as WARN.
  968. * @param detailMsg
  969. */
  970. protected void logStatusWarn(String detailMsg) throws MessagingException
  971. {
  972. getLogger().warn(getStatusReport(detailMsg).toString());
  973. }
  974. /**
  975. * Log the status the current message as ERROR.
  976. * @param detailMsg
  977. */
  978. protected void logStatusError(String detailMsg) throws MessagingException
  979. {
  980. getLogger().error(getStatusReport(detailMsg).toString());
  981. }
  982. /**
  983. * Answer a <code>StringBuffer</code> containing a message reflecting
  984. * the current status of the message being processed.
  985. *
  986. * @param detailMsg
  987. * @return StringBuffer
  988. */
  989. protected StringBuffer getStatusReport(String detailMsg) throws MessagingException
  990. {
  991. StringBuffer messageBuffer = new StringBuffer(detailMsg);
  992. if (detailMsg.length() > 0)
  993. messageBuffer.append(' ');
  994. messageBuffer.append("Message ID: ");
  995. messageBuffer.append(getMessageIn().getMessageID());
  996. messageBuffer.append(". Flags: Seen = ");
  997. messageBuffer.append(new Boolean(isMessageSeen()));
  998. messageBuffer.append(", Delete = ");
  999. messageBuffer.append(new Boolean(isMessageDeleted()));
  1000. messageBuffer.append('.');
  1001. return messageBuffer;
  1002. }
  1003. /**
  1004. * Returns the userUndefined.
  1005. * @return boolean
  1006. */
  1007. protected boolean isUserUndefined()
  1008. {
  1009. return fieldUserUndefined;
  1010. }
  1011. /**
  1012. * Is the DELETED flag set?
  1013. * @throws MessagingException
  1014. */
  1015. protected boolean isMessageDeleted() throws MessagingException
  1016. {
  1017. return getMessageIn().isSet(Flags.Flag.DELETED);
  1018. }
  1019. /**
  1020. * Is the SEEN flag set?
  1021. * @throws MessagingException
  1022. */
  1023. protected boolean isMessageSeen() throws MessagingException
  1024. {
  1025. return getMessageIn().isSet(Flags.Flag.SEEN);
  1026. }
  1027. /**
  1028. * Set the DELETED flag.
  1029. * @throws MessagingException
  1030. */
  1031. protected void setMessageDeleted() throws MessagingException
  1032. {
  1033. getMessageIn().setFlag(Flags.Flag.DELETED, true);
  1034. }
  1035. /* /**
  1036. * Set the SEEN flag.
  1037. * @throws MessagingException
  1038. */
  1039. protected void setMessageSeen() throws MessagingException
  1040. {
  1041. // If the Seen flag is not handled by the folder
  1042. // allow a handler to do whatever it deems necessary
  1043. if (!getMessageIn()
  1044. .getFolder()
  1045. .getPermanentFlags()
  1046. .contains(Flags.Flag.SEEN))
  1047. handleMarkSeenNotPermanent();
  1048. else
  1049. getMessageIn().setFlag(Flags.Flag.SEEN, true);
  1050. }
  1051. /**
  1052. * <p>Handler for when the folder does not support the SEEN flag.
  1053. * The default behaviour implemented here is to log a warning and set the
  1054. * flag anyway.</p>
  1055. *
  1056. * <p> Subclasses may choose to override this and implement their own
  1057. * solutions.</p>
  1058. *
  1059. * @throws MessagingException
  1060. */
  1061. protected void handleMarkSeenNotPermanent() throws MessagingException
  1062. {
  1063. getMessageIn().setFlag(Flags.Flag.SEEN, true);
  1064. logStatusWarn("Message marked as SEEN, but the folder does not support a permanent SEEN flag.");
  1065. }
  1066. /**
  1067. * Returns the Blacklisted.
  1068. * @return boolean
  1069. */
  1070. protected boolean isBlacklistedRecipient()
  1071. {
  1072. return fieldBlacklistedRecipient;
  1073. }
  1074. /**
  1075. * Sets the localRecipient.
  1076. * @param localRecipient The localRecipient to set
  1077. */
  1078. protected void setRemoteRecipient(boolean localRecipient)
  1079. {
  1080. fieldRemoteRecipient = localRecipient;
  1081. }
  1082. /**
  1083. * Sets the userUndefined.
  1084. * @param userUndefined The userUndefined to set
  1085. */
  1086. protected void setUserUndefined(boolean userUndefined)
  1087. {
  1088. fieldUserUndefined = userUndefined;
  1089. }
  1090. /**
  1091. * Adds the mail attributes to a <code>Mail</code>.
  1092. * @param aMail a Mail instance
  1093. */
  1094. protected void addMailAttributes(Mail aMail) throws MessagingException
  1095. {
  1096. aMail.setAttribute(
  1097. getAttributePrefix() + "taskName",
  1098. getFetchTaskName());
  1099. aMail.setAttribute(
  1100. getAttributePrefix() + "folderName",
  1101. getMessageIn().getFolder().getFullName());
  1102. if (isRemoteRecipient())
  1103. aMail.setAttribute(
  1104. getAttributePrefix() + "isRemoteRecipient",
  1105. null);
  1106. if (isUserUndefined())
  1107. aMail.setAttribute(getAttributePrefix() + "isUserUndefined", null);
  1108. if (isBlacklistedRecipient())
  1109. aMail.setAttribute(
  1110. getAttributePrefix() + "isBlacklistedRecipient",
  1111. null);
  1112. if (isRecipientNotFound())
  1113. aMail.setAttribute(
  1114. getAttributePrefix() + "isRecipientNotFound",
  1115. null);
  1116. if (isMaxMessageSizeExceeded().booleanValue())
  1117. aMail.setAttribute(
  1118. getAttributePrefix() + "isMaxMessageSizeExceeded",
  1119. new Integer(getMessageIn().getSize()).toString());
  1120. if (isRemoteReceivedHeaderInvalid().booleanValue())
  1121. aMail.setAttribute(
  1122. getAttributePrefix() + "isRemoteReceivedHeaderInvalid",
  1123. null);
  1124. }
  1125. /**
  1126. * Adds any required error messages to a <code>Mail</code>.
  1127. * @param aMail a Mail instance
  1128. */
  1129. protected void addErrorMessages(Mail mail) throws MessagingException
  1130. {
  1131. if (isMaxMessageSizeExceeded().booleanValue())
  1132. {
  1133. StringBuffer msgBuffer =
  1134. new StringBuffer("550 - Rejected - This message has been rejected as the message size of ");
  1135. msgBuffer.append(getMessageIn().getSize() * 1000 / 1024 / 1000f);
  1136. msgBuffer.append("KB exceeds the maximum permitted size of ");
  1137. msgBuffer.append(getMaxMessageSizeLimit() / 1024);
  1138. msgBuffer.append("KB.");
  1139. mail.setErrorMessage(msgBuffer.toString());
  1140. }
  1141. }
  1142. /**
  1143. * Sets the Blacklisted.
  1144. * @param blacklisted The blacklisted to set
  1145. */
  1146. protected void setBlacklistedRecipient(boolean blacklisted)
  1147. {
  1148. fieldBlacklistedRecipient = blacklisted;
  1149. }
  1150. /**
  1151. * Returns the recipientNotFound.
  1152. * @return boolean
  1153. */
  1154. protected boolean isRecipientNotFound()
  1155. {
  1156. return fieldRecipientNotFound;
  1157. }
  1158. /**
  1159. * Sets the recipientNotFound.
  1160. * @param recipientNotFound The recipientNotFound to set
  1161. */
  1162. protected void setRecipientNotFound(boolean recipientNotFound)
  1163. {
  1164. fieldRecipientNotFound = recipientNotFound;
  1165. }
  1166. /**
  1167. * Returns the remoteDomain, lazily initialised as required.
  1168. * @return String
  1169. */
  1170. protected String getRemoteDomain() throws MessagingException
  1171. {
  1172. String remoteDomain;
  1173. if (null == (remoteDomain = getRemoteDomainBasic()))
  1174. {
  1175. updateRemoteDomain();
  1176. return getRemoteDomain();
  1177. }
  1178. return remoteDomain;
  1179. }
  1180. /**
  1181. * Returns the remoteDomain.
  1182. * @return String
  1183. */
  1184. private String getRemoteDomainBasic()
  1185. {
  1186. return fieldRemoteDomain;
  1187. }
  1188. /**
  1189. * Sets the remoteDomain.
  1190. * @param remoteDomain The remoteDomain to set
  1191. */
  1192. protected void setRemoteDomain(String remoteDomain)
  1193. {
  1194. fieldRemoteDomain = remoteDomain;
  1195. }
  1196. /**
  1197. * Updates the remoteDomain.
  1198. */
  1199. protected void updateRemoteDomain() throws MessagingException
  1200. {
  1201. setRemoteDomain(computeRemoteDomain());
  1202. }
  1203. /**
  1204. * Answer the IP Address of the remote server for the message being
  1205. * processed.
  1206. * @return String
  1207. * @throws MessagingException
  1208. * @throws UnknownHostException
  1209. */
  1210. protected String computeRemoteAddress()
  1211. throws MessagingException, UnknownHostException
  1212. {
  1213. String domain = getRemoteDomain();
  1214. String address = null;
  1215. String validatedAddress = null;
  1216. int ipAddressStart = domain.indexOf('[');
  1217. int ipAddressEnd = -1;
  1218. if (ipAddressStart > -1)
  1219. ipAddressEnd = domain.indexOf(']', ipAddressStart);
  1220. if (ipAddressEnd > -1)
  1221. address = domain.substring(ipAddressStart + 1, ipAddressEnd);
  1222. else
  1223. {
  1224. int hostNameEnd = domain.indexOf(' ');
  1225. if (hostNameEnd == -1)
  1226. hostNameEnd = domain.length();
  1227. address = domain.substring(0, hostNameEnd);
  1228. }
  1229. validatedAddress = org.apache.james.dnsserver.DNSServer.getByName(address).getHostAddress();
  1230. return validatedAddress;
  1231. }
  1232. /**
  1233. * Answer the Canonical host name of the remote server for the message
  1234. * being processed.
  1235. * @return String
  1236. * @throws MessagingException
  1237. * @throws UnknownHostException
  1238. */
  1239. protected String computeRemoteHostName()
  1240. throws MessagingException, UnknownHostException
  1241. {
  1242. // These shenanigans are required to get the fully qualified
  1243. // hostname prior to JDK 1.4 in which get getCanonicalHostName()
  1244. // does the job for us
  1245. InetAddress addr1 = org.apache.james.dnsserver.DNSServer.getByName(getRemoteAddress());
  1246. InetAddress addr2 = org.apache.james.dnsserver.DNSServer.getByName(addr1.getHostAddress());
  1247. return addr2.getHostName();
  1248. }
  1249. /**
  1250. * Returns the remoteAddress, lazily initialised as required.
  1251. * @return String
  1252. */
  1253. protected String getRemoteAddress()
  1254. throws MessagingException, UnknownHostException
  1255. {
  1256. String remoteAddress;
  1257. if (null == (remoteAddress = getRemoteAddressBasic()))
  1258. {
  1259. updateRemoteAddress();
  1260. return getRemoteAddress();
  1261. }
  1262. return remoteAddress;
  1263. }
  1264. /**
  1265. * Returns the remoteAddress.
  1266. * @return String
  1267. */
  1268. private String getRemoteAddressBasic()
  1269. {
  1270. return fieldRemoteAddress;
  1271. }
  1272. /**
  1273. * Returns the remoteHostName, lazily initialised as required.
  1274. * @return String
  1275. */
  1276. protected String getRemoteHostName()
  1277. throws MessagingException, UnknownHostException
  1278. {
  1279. String remoteHostName;
  1280. if (null == (remoteHostName = getRemoteHostNameBasic()))
  1281. {
  1282. updateRemoteHostName();
  1283. return getRemoteHostName();
  1284. }
  1285. return remoteHostName;
  1286. }
  1287. /**
  1288. * Returns the remoteHostName.
  1289. * @return String
  1290. */
  1291. private String getRemoteHostNameBasic()
  1292. {
  1293. return fieldRemoteHostName;
  1294. }
  1295. /**
  1296. * Sets the remoteAddress.
  1297. * @param remoteAddress The remoteAddress to set
  1298. */
  1299. protected void setRemoteAddress(String remoteAddress)
  1300. {
  1301. fieldRemoteAddress = remoteAddress;
  1302. }
  1303. /**
  1304. * Updates the remoteAddress.
  1305. */
  1306. protected void updateRemoteAddress()
  1307. throws MessagingException, UnknownHostException
  1308. {
  1309. setRemoteAddress(computeRemoteAddress());
  1310. }
  1311. /**
  1312. * Sets the remoteHostName.
  1313. * @param remoteHostName The remoteHostName to set
  1314. */
  1315. protected void setRemoteHostName(String remoteHostName)
  1316. {
  1317. fieldRemoteHostName = remoteHostName;
  1318. }
  1319. /**
  1320. * Updates the remoteHostName.
  1321. */
  1322. protected void updateRemoteHostName()
  1323. throws MessagingException, UnknownHostException
  1324. {
  1325. setRemoteHostName(computeRemoteHostName());
  1326. }
  1327. /**
  1328. * Returns the rFC2822RECEIVEDHeaderFields.
  1329. * @return String
  1330. */
  1331. public static String getRFC2822RECEIVEDHeaderFields()
  1332. {
  1333. return fieldRFC2822RECEIVEDHeaderFields;
  1334. }
  1335. /**
  1336. * Returns the maxMessageSizeExceeded, lazily initialised as required.
  1337. * @return Boolean
  1338. */
  1339. protected Boolean isMaxMessageSizeExceeded() throws MessagingException
  1340. {
  1341. Boolean isMaxMessageSizeExceeded = null;
  1342. if (null
  1343. == (isMaxMessageSizeExceeded = isMaxMessageSizeExceededBasic()))
  1344. {
  1345. updateMaxMessageSizeExceeded();
  1346. return isMaxMe