string getName(vmime::ref<vmime::net::message> message) { vmime::ref<const vmime::headerFieldValue> headerValue = message->getHeader()->Subject()->getValue(); vmime::ref<const vmime::text> headerText = headerValue.dynamicCast<const vmime::text>(); return headerText->getConvertedText(vmime::charset()); }
vmime::datetime getDate(vmime::ref<vmime::net::message> message) { vmime::ref<const vmime::headerFieldValue> headerValue = message->getHeader()->Date()->getValue(); vmime::ref<const vmime::datetime> headerDateTime = headerValue.dynamicCast<const vmime::datetime>(); return *headerDateTime; }
void EMailImapService::generateBundle(vmime::ref<vmime::net::message> &msg) { // Create new Bundle dtn::data::Bundle newBundle; // Clear all blocks newBundle.clear(); // Get header of mail vmime::ref<const vmime::header> header = msg->getHeader(); std::string mailID = " (ID: " + msg->getUniqueId() + ")"; // Check EMailCL version try { int version = toInt(header->findField("Bundle-EMailCL-Version")->getValue()->generate()); if(version != 1) throw IMAPException("Wrong EMailCL version found in mail" + mailID); }catch(vmime::exceptions::no_such_field&) { throw IMAPException("Field \"Bundle-EMailCL-Version\" not found in mail" + mailID); }catch(InvalidConversion&) { throw IMAPException("Field \"Bundle-EMailCL-Version\" wrong formatted in mail" + mailID); } try { newBundle.procflags = toInt(header->findField("Bundle-Flags")->getValue()->generate()); newBundle.destination = header->findField("Bundle-Destination")->getValue()->generate(); newBundle.source = dtn::data::EID(header->findField("Bundle-Source")->getValue()->generate()); newBundle.reportto = header->findField("Bundle-Report-To")->getValue()->generate(); newBundle.custodian = header->findField("Bundle-Custodian")->getValue()->generate(); newBundle.timestamp = toInt(header->findField("Bundle-Creation-Time")->getValue()->generate()); newBundle.sequencenumber = toInt(header->findField("Bundle-Sequence-Number")->getValue()->generate()); newBundle.lifetime = toInt(header->findField("Bundle-Lifetime")->getValue()->generate()); }catch(vmime::exceptions::no_such_field&) { throw IMAPException("Missing bundle headers in mail" + mailID); }catch(InvalidConversion&) { throw IMAPException("Wrong formatted bundle headers in mail" + mailID); } // If bundle is a fragment both fields need to be set try { newBundle.fragmentoffset = toInt(header->findField("Bundle-Fragment-Offset")->getValue()->generate()); newBundle.appdatalength = toInt(header->findField("Bundle-Total-Application-Data-Unit-Length")->getValue()->generate()); }catch(vmime::exceptions::no_such_field&) { newBundle.fragmentoffset = 0; newBundle.appdatalength = 0; }catch(InvalidConversion&) { throw IMAPException("Wrong formatted fragment offset in mail" + mailID); } //Check if bundle is already in the storage try { if(dtn::core::BundleCore::getInstance().getRouter().isKnown(newBundle)) throw IMAPException("Bundle in mail" + mailID + " already processed"); } catch (dtn::storage::NoBundleFoundException&) { // Go ahead } // Validate the primary block try { dtn::core::BundleCore::getInstance().validate((dtn::data::PrimaryBlock)newBundle); }catch(dtn::data::Validator::RejectedException&) { throw IMAPException("Bundle in mail" + mailID + " was rejected by validator"); } // Get names of additional blocks std::vector<vmime::ref<vmime::headerField> > additionalBlocks = header.constCast<vmime::header>()->findAllFields("Bundle-Additional-Block"); std::vector<std::string> additionalBlockNames; for(std::vector<vmime::ref<vmime::headerField> >::iterator it = additionalBlocks.begin(); it != additionalBlocks.end(); ++it) { additionalBlockNames.push_back((*it)->getValue()->generate()); } // Get all attachments std::vector<vmime::ref<const vmime::attachment> > attachments = vmime::attachmentHelper::findAttachmentsInMessage(msg->getParsedMessage()); // Extract payload block info size_t payloadFlags; std::string payloadName; try { payloadFlags = toInt(header->findField("Bundle-Payload-Flags")->getValue()->generate()); // Payload length will be calculated automatically //length = toInt(header->findField("Bundle-Payload-Block-Length")->getValue()->generate()); payloadName = header->findField("Bundle-Payload-Data-Name")->getValue()->generate(); }catch(vmime::exceptions::no_such_field&) { // No payload block there }catch(InvalidConversion&) { throw IMAPException("Wrong formatted payload flags in mail" + mailID); } // Create new bundle builder dtn::data::BundleBuilder builder(newBundle); // Download attachments for(std::vector<vmime::ref<const vmime::attachment> >::iterator it = attachments.begin(); it != attachments.end(); ++it) { if((*it)->getName().getBuffer() == payloadName && !payloadName.empty()) { dtn::data::PayloadBlock &pb = newBundle.push_back<dtn::data::PayloadBlock>(); // Set data ibrcommon::BLOB::Reference ref = pb.getBLOB(); ibrcommon::BLOB::iostream payloadData = ref.iostream(); vmime::utility::outputStreamAdapter data((*payloadData)); (*it)->getData()->extract(data); // Set flags setProcFlags(pb, payloadFlags); continue; } // If current attachment name is contained in additional attachment list if(std::find(additionalBlockNames.begin(), additionalBlockNames.end(), (*it)->getName().getBuffer()) != additionalBlockNames.end()) { // Search for the block type block_t blockType; try { blockType = toInt((*it)->getHeader()->findField("Block-Type")->getValue()->generate()); }catch(vmime::exceptions::no_such_field&) { throw IMAPException("Block type not found in attachment of mail" + mailID); } // Search for processing flags size_t flags; try { flags = toInt((*it)->getHeader()->findField("Block-Processing-Flags")->getValue()->generate()); }catch(vmime::exceptions::no_such_field&) { throw IMAPException("Missing block processing flags in extension attachment of mail" + mailID); }catch(InvalidConversion&) { throw IMAPException("Wrong formatted processing flags in extension attachment of mail" + mailID); } // Create a block object dtn::data::Block &block = builder.insert(blockType, flags); // Add EIDs try { addEIDList(block, (*it)); }catch(InvalidConversion&) { throw IMAPException("Wrong formatted EID list in extension attachment of mail" + mailID); } // Get payload of current block std::stringstream ss; vmime::utility::outputStreamAdapter data(ss); (*it)->getData()->extract(data); block.deserialize(ss, ss.str().length()); } } // Validate whole bundle try { dtn::core::BundleCore::getInstance().validate(newBundle); }catch(dtn::data::Validator::RejectedException&) { throw IMAPException("Bundle in mail" + mailID + " was rejected by validator"); } // create a filter context dtn::core::FilterContext context; context.setProtocol(dtn::core::Node::CONN_EMAIL); // push bundle through the filter routines context.setBundle(newBundle); BundleFilter::ACTION ret = dtn::core::BundleCore::getInstance().filter(dtn::core::BundleFilter::INPUT, context, newBundle); if (ret == BundleFilter::ACCEPT) { // Raise default bundle received event dtn::net::BundleReceivedEvent::raise(newBundle.source, newBundle, false); } }