Bonjour à tous,
Je code en c++/qt et j'essaye d'utiler CurlLibrairie pour envoyer un email avec une pièce jointe,
l'email et reçu ainsi que les piece jointes en en format text, par contre tout ce qui est PDF ou image arrive corrompu, par fois sur les pdf il y a juste le filigrane qui est afficher
voici mon fichier main.cpp
#include <QCoreApplication>
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include <ctime>
#include <sstream>
#include <iostream>
#include <fstream>
#define FROM_ADDR "***@***"
#define TO_ADDR "***@***"
#define CC_ADDR "***@***"
#define FROM_MAIL "Sender Person <" FROM_ADDR ">"
#define TO_MAIL "A Receiver <" TO_ADDR ">"
#define CC_MAIL "John CC Smith <" CC_ADDR ">"
std::string getCurrentDate() {
char buffer[100];
time_t now = time(0);
struct tm tstruct;
tstruct = *gmtime(&now);
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S %z", &tstruct);
return std::string(buffer);
}
std::string createPayloadText() {
std::ostringstream ss;
ss << "The body of the message starts here.\r\n"
<< "\r\n"
<< "Vous trouverez ci-joint à ce message votre facture chez SOLECTROM.\r\n"
<< "Check RFC 5322.\r\n";
return ss.str();
}
bool fileExists(const std::string& path) {
std::ifstream file(path);
return file.good();
}
std::string readFile(const std::string& filePath) {
std::ifstream file(filePath, std::ios::binary);
if (!file) {
throw std::runtime_error("Cannot open file: " + filePath);
}
std::ostringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}
int main(void) {
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
struct curl_slist *headers = NULL;
curl = curl_easy_init();
if (curl) {
curl_mime *mime;
curl_mimepart *part;
const char *ca_cert_path = "C:/Data/Fichiers_applications/C++/LibrairiesExternes/Certificats/cacert.pem-master/cacert.pem";
if (!fileExists(ca_cert_path)) {
std::cerr << "Certificate file not found at " << ca_cert_path << std::endl;
return 1;
} else {
std::cerr << "Certificate file found at " << ca_cert_path << std::endl;
}
curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.gmail.com:587");
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_CAPATH, ca_cert_path);
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_ADDR);
recipients = curl_slist_append(recipients, TO_ADDR);
recipients = curl_slist_append(recipients, CC_ADDR);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
// Set the headers
headers = curl_slist_append(headers, ("Date: " + getCurrentDate()).c_str());
headers = curl_slist_append(headers, ("To: " + std::string(TO_MAIL)).c_str());
headers = curl_slist_append(headers, ("From: " + std::string(FROM_MAIL)).c_str());
headers = curl_slist_append(headers, ("Cc: " + std::string(CC_MAIL)).c_str());
headers = curl_slist_append(headers, "Message-ID: <***@***>");
headers = curl_slist_append(headers, "Subject: Votre facture SOLECTROM");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// Create the MIME structure
mime = curl_mime_init(curl);
// Add the message part
part = curl_mime_addpart(mime);
curl_mime_data(part, createPayloadText().c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "text/plain");
// Read the PDF file manually
const char *pdf_path = "C:/Data/Fichiers_applications/C++/Projets_QtCreator/Tests/testCurlConsole/testCurlConsole/facture.pdf";
if (!fileExists(pdf_path)) {
std::cerr << "PDF file not found at " << pdf_path << std::endl;
return 1;
}
std::string pdfContent = readFile(pdf_path);
// Add the attachment part
part = curl_mime_addpart(mime);
curl_mime_data(part, pdfContent.c_str(), pdfContent.size());
curl_mime_filename(part, "facture.pdf"); // Name of the file as it will appear in the email
curl_mime_type(part, "application/pdf"); // MIME type for PDF
// Set the MIME structure
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
curl_easy_setopt(curl, CURLOPT_USERNAME, "***@***");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "mdp perso"); // Remplacez par votre mot de passe d'application Gmail
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
curl_slist_free_all(recipients);
curl_slist_free_all(headers); // Free the headers
curl_mime_free(mime); // Free the MIME structure
curl_easy_cleanup(curl);
}
return (int)res;
}
C'est quelqu'un a une idée SVP, je suis bloqué depuis quelques jours.
Merci d'avance
Je n'ai jamais fait cela avec libcurl, mais je pense que tu dois encoder ton fichier .pdf en base64 car tu ne peux pas envoyer le contenu binaire du .pdf par e-mail, ce n'est simplement pas supporté par les protocoles.
Essaye d'encoder ta partie mime contenant le .pdf avec curl_mime_encoder() en spécifiant le format d'encodage "base64" :
Cela t'évitera de lire ton fichier avec readFile() dans une std::string C++ en amont et remplacera curl_mime_data() et curl_mime_filename() (le nom du fichier est apposé en même temps).
Aussi, n'oublie pas que les différentes fonctions de libcurl retournent des valeurs qui te permettent de vérifier que tout s'est bien passé.
Un code robuste vérifie ces valeurs et agit en conséquence.
Merci beaucoup de prendre le temps de me répondre, et surtout merci pour tes conseils et tes observations, je fais les modifs et je tiendrai au courant.
Autre observation : tu peux aussi utiliser curl_mime_filedata() pour mettre ton fichier .pdf dans ta partie mime
https://curl.se/libcurl/c/curl_mime_filedata.html
Cela t'évitera de lire ton fichier avec readFile() dans une std::string C++ en amont et remplacera curl_mime_data() et curl_mime_filename() (le nom du fichier est apposé en même temps).
Aussi, n'oublie pas que les différentes fonctions de libcurl retournent des valeurs qui te permettent de vérifier que tout s'est bien passé.
Un code robuste vérifie ces valeurs et agit en conséquence.