fix curl filter / fix BOTH

This commit is contained in:
2022-12-27 10:14:47 +01:00
parent 53c5c29a14
commit 285792acfc
8 changed files with 243 additions and 85 deletions

View File

@ -157,6 +157,35 @@ kaz::operator >> (istream &in, AttachMode &attachMode) {
return in;
}
// ================================================================================
const string
kaz::headerTypeLabels[] = {
"Same", "Multi", "MainPlain", "AttachHtml"
};
const map<string, HeaderType>
kaz::headerTypeMap = boost::assign::map_list_of
("same", SAME)
("multi", MULTI)
("mainplain", MAIN_PLAIN)
("attachhtml", ATTACH_HTML)
;
ostream &
kaz::operator << (ostream &out, const HeaderType &headerType) {
//BOOST_ASSERT (treeType >= MIN && treeType <= ALPHA);
return out << headerTypeLabels [headerType];
}
istream &
kaz::operator >> (istream &in, HeaderType &headerType) {
string token;
in >> token;
auto pos = headerTypeMap.find (boost::algorithm::to_lower_copy (token));
if (pos == headerTypeMap.end ())
in.setstate (ios_base::failbit);
else
headerType = pos->second;
return in;
}
// ================================================================================
void
MainAttachment::copy (ifstream &mbox, ofstream &outbox, const streamoff &begin, const streamoff &end) {
@ -420,6 +449,7 @@ MainAttachment::extractPreviousKAZ (ifstream &mbox) {
void
MainAttachment::removePreviousArchive () {
DEF_LOG ("MainAttachment::removePreviousArchive", "");
vector<string> toRemove;
for (map <string, string>::const_iterator it = previousLinks.begin (); it != previousLinks.end (); ++it) {
const string key (it->first);
@ -430,6 +460,41 @@ MainAttachment::removePreviousArchive () {
previousLinks.erase (old);
}
// ================================================================================
void MainAttachment::rewriteHeaders (ifstream &mbox, ofstream &outbox, const HeaderType &headerType) {
DEF_LOG ("MainAttachment::rewriteHeaders", "headerType: " << headerType);
if (SAME == headerType) {
copy (mbox, outbox, 0, contentPos);
return;
}
string mime (getMime (mbox));
string::size_type startPos = (0);
for (string token : {string ("content-transfer-encoding"), Attachment::contentTypeToken}) {
startPos = caseInsensitiveFind (mime, token);
for (string::size_type stopPos (startPos);
(stopPos = mime.find ("\n", stopPos)) != string::npos;
) {
if (string (" \t").find (mime [stopPos+1]) == string::npos) {
mime.erase (startPos, stopPos-startPos);
break;
}
}
}
string contentType (KAZ_EMPTY_TEXT_PLAIN);
switch (headerType) {
case SAME: /* no way */;
case MAIN_PLAIN: contentType = KAZ_EMPTY_TEXT_PLAIN; break;
case ATTACH_HTML: contentType = KAZ_ATTACHMENT_TEXT_HTML; break;
case MULTI:
boundary = "__KAZ__"+boundaryGen (40);
contentType = "Content-Type: multipart/mixed; boundary=\""+boundary+"\"";
boundary = "--"+boundary+"--";
boundaryMiddleSize = boundary.length () - 2;
}
mime.insert (startPos, contentType);
outbox << mime << flush;
}
// ================================================================================
MainAttachment::MainAttachment (ifstream &mbox)
: Attachment (mbox, initTmpLevel (), 0, initTmpPos ()),
@ -566,6 +631,15 @@ MainAttachment::extract (ifstream &mbox, const SizeArg &minSize) const {
}
// ================================================================================
/*!
Régle à appliquer dans le cas où Kaz ajoute son cartouche et que le corps principale n'est pas multipart :
<table>
<tr><th>src</th><th>FOOTER</th><th>BOTH</th><th>ATTCH</th></tr>
<tr><th>text/plain</th><td>OK</td><td>mute multi</td><td>mute multi</td></tr>
<tr><th>empty mail</th><td>mute plain</td><td>mute multi</td><td>mute html</td></tr>
</table>
*/
void
MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &minSize, AttachMode attachMode) {
DEF_LOG ("MainAttachment::substitute", "minSize: " << minSize << " AttachMode: " << attachMode);
@ -600,53 +674,55 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
string plainDisclaim, htmlDisclaim;
getDisclaim (plainDisclaim, htmlDisclaim);
HeaderType headerType (SAME);
// copy email
if (!boundary.size () && plainDisclaim.size ()) {
if (attachMode & ATTACHMENT)
attachMode = FOOTER;
if (emptyEMail) {
// only one attachment must be replace
cerr << "eMailShrinker: force one attachment" << endl;
string mime (getMime (mbox));
string::size_type startPos = (0);
for (string token : {string ("Content-Transfer-Encoding"), Attachment::contentTypeToken}) {
startPos = caseInsensitiveFind (mime, "Content-Transfer-Encoding");
for (string::size_type stopPos (startPos);
(stopPos = mime.find ("\n", stopPos)) != string::npos;
) {
if (string (" \t").find (mime [stopPos+1]) == string::npos) {
mime.erase (startPos, stopPos-startPos);
break;
}
}
}
mime.insert (startPos, KAZ_EMPTY_TEXT_PLAIN);
string content (plainDisclaim);
base64Encode (content);
outbox << mime
<< content << endl;
outbox.flush ();
outbox.close ();
return;
if (!boundary.size () && plainDisclaim.size ())
switch (attachMode) {
case NONE: LOG_BUG (true, /* */, "eMailShrinker: bug M12: nothing to do"); break;
case FOOTER: headerType = (emptyEMail ? MAIN_PLAIN : SAME); break;
case BOTH: headerType = MULTI; break;
case ATTACHMENT: headerType = ATTACH_HTML; break;
}
}
streamoff curPos = 0;
copy (mbox, outbox, curPos, contentPos);
curPos = contentPos;
rewriteHeaders (mbox, outbox, headerType);
streamoff curPos = contentPos;
if (plainDisclaim.size ()) {
if (emptyEMail && (attachMode & FOOTER)) {
// check no main text
LOG ("Force main text");
cerr << "eMailShrinker: force footer" << endl;
if (MAIN_PLAIN == headerType) {
LOG ("Replace old content with plain");
string content (plainDisclaim);
base64Encode (content);
outbox << boundary.substr (0, boundary.length () -2) << endl
<< KAZ_EMPTY_TEXT_PLAIN << endl
<< content << endl;
outbox << content << endl;
outbox.flush ();
}
return;
}
if (ATTACH_HTML == headerType) {
LOG ("Replace old content with html");
string content (plainDisclaim);
base64Encode (content);
outbox << content << endl;
outbox.flush ();
return;
}
if (plainDisclaim.size () && emptyEMail && (attachMode & FOOTER)) {
// case : multi
LOG ("Force main text");
cerr << "eMailShrinker: force main text" << endl;
string content (plainDisclaim);
base64Encode (content);
outbox << boundary.substr (0, boundary.length () -2) << endl
<< KAZ_EMPTY_TEXT_PLAIN << endl
<< content << endl;
outbox.flush ();
}
if (MULTI == headerType) {
LOG ("New boundary");
map<string, string>::const_iterator it (env.find (contentTypeToken));
LOG_BUG (it == env.end (), /* */, "eMailShrinker: bug M13: no content-type");
outbox << boundary.substr (0, boundary.length () -2) << endl
<< Attachment::contentTypeToken << ": " << it->second << endl;
}
for (Attachment *attachP : allMarkedPtrs) {
copy (mbox, outbox, curPos, attachP->beginInParent);
LOG_BUG (attachP->toUpdate && attachP->toExtract, /**/, "eMailShrinker: bug M5: update and extract. pos: " << attachP->beginPos);
@ -727,12 +803,15 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
outbox.flush ();
curPos = attachP->endPos;
}
if (plainDisclaim.size () && (attachMode & ATTACHMENT)) {
LOG ("Add kaz attachment");
cerr << "eMailShrinker: force attachment" << endl;
streamoff lastPos = subAttachements.back ().endPos;
copy (mbox, outbox, curPos, lastPos);
curPos = lastPos;
if (subAttachements.size ()) {
streamoff lastPos = subAttachements.back ().endPos;
copy (mbox, outbox, curPos, lastPos);
curPos = lastPos;
}
string content (KAZ_HTML_CONTENT+htmlDisclaim+BODY_END+HTML_END);
base64Encode (content);
@ -742,7 +821,8 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
outbox.flush ();
}
copy (mbox, outbox, curPos, endPos);
//outbox << endl;
if (MULTI == headerType)
outbox << boundary.substr (0, boundary.length ()) << endl;
outbox.close ();
}

View File

@ -33,8 +33,8 @@
////////////////////////////////////////////////////////////////////////////
#include "version.hpp"
const std::string kaz::LAST_VERSION_NUM ("2.9");
const std::string kaz::LAST_VERSION_DATE ("2022-12-24");
const std::string kaz::LAST_VERSION_NUM ("2.10");
const std::string kaz::LAST_VERSION_DATE ("2022-12-27");
const std::string kaz::LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" eMailShrinker");
#include <iostream>

View File

@ -175,6 +175,19 @@ kaz::caseInsensitiveRFind (const string& s, const string& pattern, const string:
return s.rend () - it - pattern.length ();
}
string
kaz::boundaryGen (const int &size) {
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
string result;
result.reserve (size);
for (int i = 0; i < size; ++i)
result += alphanum[rand() % (sizeof (alphanum) - 1)];
return result;
}
// ================================================================================
template<char delim>
void