dsnbounce.java

来自「邮件服务器系统 支持SMTP POP3 是著名的Apache写 有一定的参考」· Java 代码 · 共 974 行 · 第 1/3 页

JAVA
974
字号
        public static final String DELIVERY_VERSION = "5.5";        /**         * Message Content or Media Status         */        public static final int CONTENT = 6;        /**         * Other or undefined media error         */        public static final String CONTENT_OTHER = "6.0";        /**         * Media not supported         */        public static final String CONTENT_UNSUPPORTED = "6.1";        /**         * Conversion required and prohibited         */        public static final String CONTENT_CONVERSION_NOT_ALLOWED = "6.2";        /**         * Conversion required, but not supported         */        public static final String CONTENT_CONVERSION_NOT_SUPPORTED = "6.3";        /**         * Conversion with loss performed         */        public static final String CONTENT_CONVERSION_LOSS = "6.4";        /**         * Conversion failed         */        public static final String CONTENT_CONVERSION_FAILED = "6.5";        /**         * Security or Policy Status         */        public static final int SECURITY = 7;        /**         * Other or undefined security status         */        public static final String SECURITY_OTHER = "7.0";        /**         * Delivery not authorized, message refused         */        public static final String SECURITY_AUTH = "7.1";        /**         * Mailing list expansion prohibited         */        public static final String SECURITY_LIST_EXP = "7.2";        /**         * Security conversion required, but not possible         */        public static final String SECURITY_CONVERSION = "7.3";        /**         * Security features not supported         */        public static final String SECURITY_UNSUPPORTED = "7.4";        /**         * Cryptographic failure         */        public static final String SECURITY_CRYPT_FAIL = "7.5";        /**         * Cryptographic algorithm not supported         */        public static final String SECURITY_CRYPT_ALGO = "7.6";        /**         * Message integrity failure         */        public static final String SECURITY_INTEGRITY = "7.7";        // get methods        public static String getStatus(int type, String detail) {            return type + "." + detail;        }        public static String getStatus(int type, int subject, int detail) {            return type + "." + subject + "." + detail;        }    }    private static final RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();    //  Used to generate new mail names    private static final java.util.Random random = new java.util.Random();    // regexp pattern for scaning status code from exception message    private static Pattern statusPattern;    private static Pattern diagPattern;    private static final String MACHINE_PATTERN = "[machine]";    private String messageString =        "Hi. This is the James mail server at [machine].\nI'm afraid I wasn't able to deliver your message to the following addresses.\nThis is a permanent error; I've given up. Sorry it didn't work out.  Below\nI include the list of recipients and the reason why I was unable to deliver\nyour message.\n";    /*     * Static initializer.<p>     * Compiles patterns for processing exception messages.<p>     */    static {        Perl5Compiler compiler = new Perl5Compiler();        String status_pattern_string = ".*\\s*([245]\\.\\d{1,3}\\.\\d{1,3}).*\\s*";        String diag_pattern_string = "^\\d{3}\\s.*$";        try {            statusPattern = compiler.                compile(status_pattern_string, Perl5Compiler.READ_ONLY_MASK);        } catch(MalformedPatternException mpe) {            //this should not happen as the pattern string is hardcoded.            System.err.println ("Malformed pattern: " + status_pattern_string);            mpe.printStackTrace (System.err);        }        try {            diagPattern = compiler.                compile(diag_pattern_string, Perl5Compiler.READ_ONLY_MASK);        } catch(MalformedPatternException mpe) {            //this should not happen as the pattern string is hardcoded.            System.err.println ("Malformed pattern: " + diag_pattern_string);        }    }    /**     * Initialize the mailet     */    public void init() throws MessagingException {        super.init();        if (getInitParameter("messageString") != null) {            messageString = getInitParameter("messageString");        }                MailcapCommandMap mail_cap =            (MailcapCommandMap) CommandMap.getDefaultCommandMap();        mail_cap.addMailcap ("message/delivery-status;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");        CommandMap.setDefaultCommandMap (mail_cap);    }    /**     * Service does the hard work and bounces the originalMail in the format specified by RFC3464.     *     * @param originalMail the mail to bounce     * @throws MessagingException if a problem arises formulating the redirected mail     *     * @see org.apache.mailet.Mailet#service(org.apache.mailet.Mail)     */    public void service(Mail originalMail) throws MessagingException {        // duplicates the Mail object, to be able to modify the new mail keeping the original untouched        Mail newMail = ((MailImpl) originalMail).duplicate(newName((MailImpl) originalMail));        // We don't need to use the original Remote Address and Host,        // and doing so would likely cause a loop with spam detecting        // matchers.        try {            ((MailImpl)newMail).setRemoteAddr(java.net.InetAddress.getLocalHost().getHostAddress());            ((MailImpl)newMail).setRemoteHost(java.net.InetAddress.getLocalHost().getHostName());        } catch (java.net.UnknownHostException _) {            ((MailImpl) newMail).setRemoteAddr("127.0.0.1");            ((MailImpl) newMail).setRemoteHost("localhost");        }        MailAddress returnAddress = getExistingReturnPath(originalMail);        Collection newRecipients = new HashSet();        if (returnAddress == SpecialAddress.NULL) {            if (isDebug)                log("Processing a bounce request for a message with an empty reverse-path.  No bounce will be sent.");            if(!getPassThrough(originalMail)) {                originalMail.setState(Mail.GHOST);            }            return;        } else if (returnAddress == null) {            log("WARNING: Mail to be bounced does not contain a reverse-path.");        } else {            if (isDebug)                log("Processing a bounce request for a message with a return path header.  The bounce will be sent to " + returnAddress);        }        newRecipients.add(returnAddress);        ((MailImpl)newMail).setRecipients(newRecipients);        if (isDebug) {            MailImpl newMailImpl = (MailImpl) newMail;            log("New mail - sender: " + newMailImpl.getSender()                + ", recipients: " +                arrayToString(newMailImpl.getRecipients().toArray())                + ", name: " + newMailImpl.getName()                + ", remoteHost: " + newMailImpl.getRemoteHost()                + ", remoteAddr: " + newMailImpl.getRemoteAddr()                + ", state: " + newMailImpl.getState()                + ", lastUpdated: " + newMailImpl.getLastUpdated()                + ", errorMessage: " + newMailImpl.getErrorMessage());        }        // create the bounce message        MimeMessage newMessage =            new MimeMessage(Session.getDefaultInstance(System.getProperties(),                                                       null));        MimeMultipartReport multipart = new MimeMultipartReport ();        multipart.setReportType ("delivery-status");                // part 1: descripive text message        MimeBodyPart part1 = createTextMsg(originalMail);        multipart.addBodyPart(part1);        // part 2: DSN        MimeBodyPart part2 = createDSN(originalMail);        multipart.addBodyPart(part2);        // part 3: original mail (optional)        if (getAttachmentType() != NONE) {            MimeBodyPart part3 = createAttachedOriginal(originalMail);            multipart.addBodyPart(part3);        }        // stuffing all together        newMessage.setContent(multipart);        newMessage.setHeader(RFC2822Headers.CONTENT_TYPE, multipart.getContentType());        newMail.setMessage(newMessage);        //Set additional headers        setRecipients(newMail, getRecipients(originalMail), originalMail);        setTo(newMail, getTo(originalMail), originalMail);        setSubjectPrefix(newMail, getSubjectPrefix(originalMail), originalMail);        if(newMail.getMessage().getHeader(RFC2822Headers.DATE) == null) {            newMail.getMessage().setHeader(RFC2822Headers.DATE,rfc822DateFormat.format(new Date()));        }        setReplyTo(newMail, getReplyTo(originalMail), originalMail);        setReversePath(newMail, getReversePath(originalMail), originalMail);        setSender(newMail, getSender(originalMail), originalMail);        setIsReply(newMail, isReply(originalMail), originalMail);        newMail.getMessage().saveChanges();        getMailetContext().sendMail(newMail);        // ghosting the original mail        if(!getPassThrough(originalMail)) {            originalMail.setState(Mail.GHOST);        }    }    /**     * Create a MimeBodyPart with a textual description for human readers.     *     * @param originalMail     * @return MimeBodyPart     * @throws MessagingException     */    protected MimeBodyPart createTextMsg(Mail originalMail)        throws MessagingException {        MimeBodyPart part1 = new MimeBodyPart();        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 (messageString);        int m_idx_begin = messageString.indexOf(MACHINE_PATTERN);        if (m_idx_begin != -1) {            bounceBuffer.replace (m_idx_begin,                                  m_idx_begin+MACHINE_PATTERN.length(),                                  machine);        }        out.println(bounceBuffer.toString());        out.println("Failed recipient(s):");        for (Iterator i = originalMail.getRecipients().iterator(); i.hasNext(); ) {            out.println(i.next());        }        MessagingException ex = (MessagingException)originalMail.getAttribute("delivery-error");        out.println();        out.println("Error message:");        out.println(getErrorMsg(ex));        out.println();        part1.setText(sout.toString());        return part1;    }    /**     * creates the DSN-bodypart for automated processing     *     * @param originalMail     * @return MimeBodyPart dsn-bodypart     * @throws MessagingException     */    protected MimeBodyPart createDSN(Mail originalMail) throws MessagingException {        MimeBodyPart dsn = new MimeBodyPart();        MimeMessage dsnMessage =            new MimeMessage(Session.getDefaultInstance(System.getProperties(), null));        StringWriter sout = new StringWriter();        PrintWriter out = new PrintWriter(sout, true);        String errorMsg = null;        String nameType = null;        ////////////////////////        // per message fields //        ////////////////////////        //optional: envelope-id        // TODO: Envelope-Id        // The Original-Envelope-Id is NOT the same as the Message-Id from the header.        // The Message-Id identifies the content of the message, while the Original-Envelope-ID

⌨️ 快捷键说明

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