Exemplo n.º 1
0
void Multipart::simplifyMimeStructure()
{
    // If we're looking at a multipart with just a single part, change
    // the mime type to avoid the middle multipart. This affects
    // Kaiten Mail.
    if ( header()->contentType() &&
         header()->contentType()->type() == "multipart" &&
         parts->count() == 1 &&
         ( !parts->firstElement()->header()->contentType() ||
           parts->firstElement()->header()->contentType()->type() != "multipart" ) ) {
        Header * me = header();
        Header * sub = parts->firstElement()->header();

        me->removeField( HeaderField::ContentType );
        ContentType * ct = sub->contentType();
        if ( ct )
            me->add( ct );

        me->removeField( HeaderField::ContentTransferEncoding );
        ContentTransferEncoding * cte = sub->contentTransferEncoding();
        if ( cte )
            me->add( cte );

        me->removeField( HeaderField::ContentDisposition );
        ContentDisposition * cd = sub->contentDisposition();
        if ( cd )
            me->add( cd );

        if ( !ct && !cte && !cd )
            me->removeField( HeaderField::MimeVersion );
    }
}
Exemplo n.º 2
0
Header * Message::parseHeader( uint & i, uint end,
                               const EString & rfc2822,
                               Header::Mode m )
{
    Header * h = new Header( m );
    bool done = false;
    while ( !done ) {
        if ( i >= end )
            done = true;
        if ( rfc2822[i] == 0xEF &&
             rfc2822[i+1] == 0xBB &&
             rfc2822[i+2] == 0xBF )
            i += 3;
        uint j = i;
        while ( rfc2822[j] >=  33 &&
                rfc2822[j] <= 127 &&
                rfc2822[j] != ':' )
            j++;
        if ( j == i + 4 && m == Header::Rfc2822 &&
             rfc2822.mid( i, j-i+1 ).lower() == "from " ) {
            while ( i < end && rfc2822[i] != '\r' && rfc2822[i] != '\n' )
                i++;
            while ( rfc2822[i] == '\r' )
                i++;
            if ( rfc2822[i] == '\n' )
                i++;
        }
        else if ( j > i && rfc2822[j] == ':' ) {
            EString name = rfc2822.mid( i, j-i );
            i = j;
            i++;
            while ( rfc2822[i] == ' ' || rfc2822[i] == '\t' )
                i++;
            j = i;
            // this isn't at all pretty, is it...
            while ( j < rfc2822.length() &&
                    ( rfc2822[j] != '\n' ||
                      ( rfc2822[j] == '\n' &&
                        ( rfc2822[j+1] == ' ' || rfc2822[j+1] == '\t' ) ) ) )
                j++;
            if ( j && rfc2822[j-1] == '\r' )
                j--;
            EString value = rfc2822.mid( i, j-i );
            if ( !value.simplified().isEmpty() ||
                 name.lower().startsWith( "x-" ) ) {
                HeaderField * f = HeaderField::create( name, value );
                h->add( f );
            }
            i = j;
            if ( rfc2822[i] == '\r' && rfc2822[i+1] == '\n' )
                i++;
            i++;
        }
        else {
            done = true;
        }
    }
    return h;
}
Exemplo n.º 3
0
Injectee * DSN::result() const
{
    Injectee * r = new Injectee;
    Bodypart * plainText = new Bodypart( 1, r );
    Bodypart * dsn = new Bodypart( 2, r );
    Bodypart * original = new Bodypart( 3, r );

    plainText->setParent( r );
    dsn->setParent( r );
    original->setParent( r );
    r->children()->append( plainText );
    r->children()->append( dsn );
    r->children()->append( original );

    // set up the original message, either full or header-only
    if ( fullReport() ) {
        original->header()->add( "Content-Type", "text/rfc822-headers" );
        original->setData( message()->header()->asText() );

        // this is what we _should_ do, except that we don't. the body
        // of the message is lost, probably because original-> has a
        // null parent.

        //original->header()->add( "Content-Type", "message/rfc822" );
        //original->setMessage( message() );

        // and maybe we shouldn't anyway. sending a potentially big
        // body in a bounce is not necessarily a good idea.
    }
    else {
        // nasty mime name there
        original->header()->add( "Content-Type", "text/rfc822-headers" );
        original->setData( message()->header()->asText() );
    }

    // the from field has to contain... what? let's try this for now.
    Address * from = new Address( Configuration::hostname(),
                                  "postmaster",
                                  Configuration::hostname() );
    // set up the top-level header
    Header * h = r->header();
    if ( resultDate() ) {
        h->add( "Date", resultDate()->rfc822() );
    }
    else {
        Date * now = new Date;
        now->setCurrentTime();
        h->add( "Date", now->rfc822() );
    }
    h->add( "From", from->toString() );
    if ( sender() )
        h->add( "To", sender()->toString() );
    if ( allOk() )
        h->add( "Subject", "Message delivered" );
    else if ( allFailed() )
        h->add( "Subject", "Message delivery failed" );
    else
        h->add( "Subject", "Message delivery reports" );
    h->add( "Mime-Version", "1.0" );
    h->add( "Content-Type", "multipart/report; boundary=" +
            Message::acceptableBoundary( message()->rfc822() ) );

    // set up the plaintext and DSN parts
    // what charset should we use for plainText?
    plainText->header()->add( "Content-Type", "text/plain; format=flowed" );
    dsn->header()->add( "Content-Type", "message/delivery-status" );

    plainText->setData( plainBody() );
    dsn->setData( dsnBody() );
    r->addMessageId();

    return r;
}