Piece jointe qui arrive corrompue

Résolu
Mourad2024 Messages postés 2 Date d'inscription samedi 15 juin 2024 Statut Membre Dernière intervention 28 juin 2024 - Modifié le 27 juin 2024 à 21:53
[Dal] Messages postés 6193 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 4 juillet 2024 - 4 juil. 2024 à 09:45

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

3 réponses

[Dal] Messages postés 6193 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 4 juillet 2024 1 090
28 juin 2024 à 11:09

Salut Mourad2024,

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" :

https://curl.se/libcurl/c/curl_mime_encoder.html

0
[Dal] Messages postés 6193 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 4 juillet 2024 1 090
Modifié le 28 juin 2024 à 13:02

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.

0
Mourad2024 Messages postés 2 Date d'inscription samedi 15 juin 2024 Statut Membre Dernière intervention 28 juin 2024
28 juin 2024 à 18:21

Bonjour Dal,

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.

0
Mourad2009B Messages postés 104 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 2 juillet 2024
2 juil. 2024 à 18:53

C'était très efficace DAL, merci beaucoup pour ton aide.

0
[Dal] Messages postés 6193 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 4 juillet 2024 1 090
4 juil. 2024 à 09:45

Super, merci de ton retour :-)

0