示例#1
0
int MailMessage::parseHeaders(StringBuffer &rfcHeaders) {

    ArrayList lines;
    const StringBuffer *line;
    StringBuffer strReceived;
    bool receivedExtracted = false;
    LOG.debug("parseHeaders START");

    // Join header parts using \t or 8 blank
    StringBuffer joinlinetab("\t");
    rfcHeaders.replaceAll(joinlinetab, " ");

    StringBuffer joinlinespaces(newline);
    joinlinespaces+=" ";  // 8 blanks

    rfcHeaders.replaceAll(joinlinespaces, " ");

    rfcHeaders.split(lines, newline);

    // importance is set to "0" by default. Then there isn't anything modification
    // in the header, at the end of the loop the importance will be set to "3", default normal
    importance = "0";

    for ( line=(StringBuffer *)lines.front();
          line;
          line=(StringBuffer *)lines.next() ) {

        if( *line == "\r" )
            break;
        // The first empty line marks the end of the header section
        if( line->empty() ){
            break;
        }
        // Process the headers

        if( line->ifind(TO) == 0 ){
            to = MailMessage::decodeHeader(line->substr(TO_LEN));
        }
        else if( line->ifind(FROM) == 0 ) {
            from = MailMessage::decodeHeader(line->substr(FROM_LEN));
        }
        else if( line->ifind(CC) == 0 ) {
            cc = MailMessage::decodeHeader(line->substr(CC_LEN));
        }
        else if( line->ifind(BCC) == 0 ) {
            bcc = MailMessage::decodeHeader(line->substr(BCC_LEN));
        }
        else if ( line->ifind(DATE) == 0 ) {
            //subjectParsing = false;
            if( date.parseRfc822(line->substr(DATE_LEN)) ) {
                LOG.error("Error parsing date");
                return 500;
            }
        }
        else if( line->ifind(SUBJECT) == 0 ) {

            subject = MailMessage::decodeHeader(line->substr(SUBJECT_LEN));
            LOG.debug("SUBJECT: %s", subject.c_str());
        }
        else if( line->ifind(ENCODING) == 0 ) {  // it is here for single part only
            body.setEncoding(line->substr(ENCODING_LEN));
        }
        else if(line->ifind(MIMEVERS) == 0 ) {
            mimeVersion = line->substr(MIMEVERS_LEN);
        }
        else if(line->ifind(MESSAGEID) == 0 ) {
            messageId = line->substr(MESSAGEID_LEN);
        }
        else if(line->ifind(IMPORTANCE) == 0 ) {
            StringBuffer data = line->substr(IMPORTANCE_LEN);
            data.lowerCase();
            importance = convertImportance(data);
        }
        else if(line->ifind(X_PRIORITY) == 0 ) {
            if (importance == "0") {
                StringBuffer data = line->substr(X_PRIORITY_LEN);
                data.lowerCase();
                importance = convertXPriority(data);
            }            
        }
        else if( line->ifind(MIMETYPE) == 0 ) {

            StringBuffer sb = getTokenValue(line, MIMETYPE);

            if (sb.length() > 0)
                contentType = sb;

            sb.reset();
            sb = getTokenValue(line, "boundary=", false);

            if (sb.length() > 0) {
                boundary = sb;
            } else {
                body.setCharset(getTokenValue(line, CT_CHARSET));
            }
            /*

            size_t len = line->find(";") - MIMETYPE_LEN ;
            contentType = line->substr(MIMETYPE_LEN, len);

            // Save boundary for multipart
            size_t begin = line->ifind("boundary=");
            size_t end = StringBuffer::npos;

            if( begin != StringBuffer::npos ) {
                begin += strlen("boundary=\"");
                end = line->find("\"", begin) ;
                boundary = line->substr( begin, end-begin );
            }
            else {
                    begin=line->ifind(CT_CHARSET);
                if( begin != StringBuffer::npos ) {
                    begin += strlen(CT_CHARSET);
                    size_t end = begin;
                    size_t quote = line->find("\"", begin);
                    if (quote != StringBuffer::npos){
                        begin = quote + 1;
                        end = line->find("\"", begin) ;
                    }
                    else {
                        end = line->find(";", begin) ;
                        if (end == StringBuffer::npos) {
                            end = line->find(" ", begin);
                        }
                    }
                    body.setCharset( line->substr( begin, end-begin ) );
                }
            }
            */
        }
        else if(line->ifind(RECEIVED) == 0) {
            if (!receivedExtracted) {
                strReceived = line->substr(line->rfind(";") );

                if (!strReceived.empty()) {
                    received.parseRfc822(strReceived.substr(2));
                    receivedExtracted = true;
                }
                /*
                while (!strReceived.empty()) {
                    if (received.parseRfc822(strReceived.substr(2)) == 0) {
                        receivedExtracted = true;
                        break;
                    } else {
                        StringBuffer s(line->substr(line->rfind(strReceived.c_str())));
                        strReceived = line->substr(s.rfind(";"));
                    }
                }
                */

            }
        }
        else {
            headers.add(*(StringBuffer *)line);
        }

    }
    // If received was not found, copy send date
    if( received == BasicTime() ){
        received = date;
    }

    // if the importance is never set we put the importance to 3, normal
    if (importance == "0") {
        importance = "3";
    }

    LOG.debug("parseHeaders END");

    // FIXME: should check for mandatory headers before return 0
    return 0;
}
示例#2
0
// Return true if the instance is empty (a valid MailMessage must have a valid date that is not
// the default 1/1/1970)
bool MailMessage::empty() {
    return ( this->getDate() == BasicTime() );
}
示例#3
0
/**
 * Parse the date in RF 822 format
 *
 * Some examples:
 * Date: Fri, 01 Aug 2003 14:04:55 +0800
 * Date: Wed, 30 Jul 2003 13:24:21 -0700
 * Date: 20 Jun 2003 15:42:12 -0500
 *
 * RFC822 date time
 *
 *   date-time   =  [ day "," ] date time        ; dd mm yy
 *                                              ;  hh:mm:ss zzz
 *
 *   day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"
 *               /  "Fri"  / "Sat" /  "Sun"
 *
 *   date        =  1*2DIGIT month 2DIGIT        ; day month year
 *                                               ;  e.g. 20 Jun 82
 *
 *   month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"
 *               /  "May"  /  "Jun" /  "Jul"  /  "Aug"
 *               /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"
 *
 *   time        =  hour zone                    ; ANSI and Military
 *
 *   hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
 *                                               ; 00:00:00 - 23:59:59
 *
 *   zone        =  "UT"  / "GMT"                ; Universal Time
 *                                               ; North American : UT
 *               /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
 *               /  "CST" / "CDT"                ;  Central:  - 6/ - 5
 *               /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
 *               /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
 *               /  1ALPHA                       ; Military: Z = UT;
 *                                               ;  A:-1; (J not used)
 *                                               ;  M:-12; N:+1; Y:+12
 *               / ( ("+" / "-") 4DIGIT )        ; Local differential
 *                                               ;  hours+min. (HHMM)
**/
int BasicTime::parseRfc822(const char *date)
{

    int ret = 0;
    if (!isADate(date)) {
        return -1;
    }

    const char *days[] = {
        "Sun", "Mon", "Tue", "Wed",
        "Thu", "Fri", "Sat"
    };
    const char *months[] = {
        "Jan", "Feb", "Mar", "Apr",
        "May", "Jun", "Jul", "Aug",
        "Sep", "Oct", "Nov", "Dec"
    };
    // In some cases the day of week may initially contain the day,dayofmonth,
    // so its max length is 3+1+2
    char dayOfWeek[7] = "---,";
    char mon[4] = "---";
    char time[10] = "00:00:00";
    char timeZone[20] = "GMT";

    // Wed Feb 01 14:40:45 Europe/Amsterdam 2006
    // do we have day of week?
    const char *pdate = strstr( date, "," );
    if ( pdate == 0 ) {
        ret=sscanf(date, "%d %s %d %s %s",
            &day, mon, &year, time, timeZone);
    }
    else {
        ret=sscanf(date, "%s %d %s %d %s %s",
            dayOfWeek, &day, mon, &year, time, timeZone);
        if (ret >= 1 && ret < 6) {
            // it can be an error in the format: Mon,12 Feb 2007 09:00:01 +0100
            // the comma is attached to the day
            if (*(pdate + 1) != ' ') {
                ret = sscanf(pdate + 1, "%d %s %d %s %s",
                    &day, mon, &year, time, timeZone);

            }
        }
        // Convert day of week
        for (int i = 0; i < 7; i++) {
            if ( strncmp(days[i], dayOfWeek, 3) == 0 ) {
                weekday = i;
                break;
            }
        }
        // Do not exit on error on weekday, treat it like if it was
        // not present.
    }
    // Trap parsing error
    if(ret == EOF || ret == 0){
        return -1;
    }
    // Check validity
    if (year > 3000 || day < 0 || day > 31){
        *this = BasicTime();
        return -1;
    }

    // Get month
    int i;
    for (i = 0; i < 12; i++) {
        if ( strcmp(months[i], mon) == 0 ) {
            month = i+1;
            break;
        }
    }
    // Trap parsing error
    if (i==13) {
        return -1;
    }

    // Year ---------------------------------
    if (year <= 60) {
        year += 2000;
    } else if (year > 60 && year < 100) {
        year += 1900;
    }

    // hh:mm:ss -------------------------
    // do we have sec?
    if (strlen(time) > 6 && time[5] == ':')
        sscanf(time, "%d:%d:%d", &hour, &min, &sec);
    else
        sscanf(time, "%d:%d", &hour, &min);

    // Timezone ---------------------------------
    if ( strcmp(timeZone, "GMT") != 0 && strcmp(timeZone, "UT") != 0) {
        // is this explicit time?
        if ( timeZone[0] == '+' || timeZone[0]== '-' ) {
            char wcH[4] = "+00";
            char wcM[4] = "00";

            // get hour
            if ( strlen(timeZone) > 3) {
                wcH[0] = timeZone[0];
                wcH[1] = timeZone[1];
                wcH[2] = timeZone[2];
                wcH[3] = '\0';
            }
            // get min
            if ( strlen(timeZone) >= 5)    {
                wcM[0] = timeZone[3];
                wcM[1] = timeZone[4];
                wcM[2] = '\0';
            }
            tzHour = atoi(wcH);
            tzMin = atoi(wcM);
        }
        // otherwise it could be one string with the time
        else if ( strcmp(timeZone, "EDT") == 0) {
            tzHour = -4;
        }
        else if ( strcmp(timeZone, "EST") == 0
            ||  strcmp(timeZone, "CDT") == 0) {
                tzHour = -5;
        }
        else if ( strcmp(timeZone, "CST") == 0
            ||  strcmp(timeZone, "MDT") == 0) {
                tzHour = -6;
        }
        else if ( strcmp(timeZone, "MST") == 0
            ||  strcmp(timeZone, "PDT") == 0 ){
                tzHour = -7;
        }
        else if ( strcmp(timeZone, "PST") == 0) {
            tzHour = -8;
        }
    }

    // clean up
    return 0;
}