Вложение в C++
Письмо с текстом и файлом описывают как multipart/mixed с границей между частями.
Первая часть - обычный текст, вторая - вложение с именем файла; байты вложения задают в программе, без чтения с диска. Запишем тело, выведем его и настроим libcurl:
#include <iostream>
#include <string>
#include <cstring>
#include <curl/curl.h>
struct UploadCtx {
const std::string* data;
std::size_t offset;
};
std::size_t readCallback(
char* ptr,
std::size_t size,
std::size_t nmemb,
void* userdata
) {
UploadCtx* ctx = static_cast<UploadCtx*>(userdata);
if (ctx->offset >= ctx->data->size()) {
return 0;
}
std::size_t room = size * nmemb;
std::size_t left = ctx->data->size() - ctx->offset;
std::size_t copy = std::min(room, left);
std::memcpy(ptr, ctx->data->data() + ctx->offset, copy);
ctx->offset += copy;
return copy;
}
int main() {
std::string message =
"From: writer@example.com\r\n"
"To: ann@example.com\r\n"
"Subject: With attachment\r\n"
"MIME-Version: 1.0\r\n"
"Content-Type: multipart/mixed; boundary=\"mix1\"\r\n"
"\r\n"
"--mix1\r\n"
"Content-Type: text/plain; charset=utf-8\r\n"
"\r\n"
"See the attached note.\r\n"
"--mix1\r\n"
"Content-Type: text/plain; name=\"quote.txt\"\r\n"
"Content-Disposition: attachment; filename=\"quote.txt\"\r\n"
"\r\n"
"price=19\r\n"
"--mix1--\r\n";
std::cout << message;
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL* curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "smtp://127.0.0.1:2525");
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, "writer@example.com");
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, "ann@example.com");
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
UploadCtx ctx{&message, 0};
curl_easy_setopt(curl, CURLOPT_READFUNCTION, readCallback);
curl_easy_setopt(curl, CURLOPT_READDATA, &ctx);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
В выводе две секции между --mix1 - текст и
файл quote.txt с литералом price=19.
Так проверяют составное тело до отправки на SMTP.
Добавьте вложение data.bin из четырех байт
со значениями 1, 2, 3
и 4. Выведите тело multipart целиком.
Оставьте текстовую часть с фразой "Attached."
и вторую часть с байтами строки "ok".
Имя файла задайте "flag.txt". Выведите
сообщение и найдите в нем обе границы частей.