Problème avec un "QSslSocket" dans l'envoi d'un email.

Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025 - Modifié le 23 janv. 2025 à 11:30
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025 - 5 févr. 2025 à 18:27

​Bonjour à tous,

Pour commencer je vous expose les outils que j'utilise :

  • QtCreator comme IDE
  • C++/Qt comme langage

J’essaye de créer une application qui me permet d'envoyer un email avec une pièce jointe. Voilà ce que j'ai fait :

main.cpp

#include "mainwindow.h"
#include "smtpclient.h"
#include <QApplication>
#include <QLocale>
#include <QTranslator>
#include <QTimer>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();

    for (const QString &locale : uiLanguages) {
        const QString baseName = "Projet_test_02_Exemple_Qt_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }

    MainWindow w;
    w.show();

    QString smtpHost = "smtp.gmail.com"; //"142.250.110.108";
    quint16 smtpPort = 465; //587; //465;
    QString username = QString("m. test111@gmail.com");
    QString password = QString("xxxxxxxxxxxxxxxxxxxx");

    QString from = "m.test111@gmail.com";
    QString to = "reception@gmail.com";
    QString subject = "Test d'email avec pièce jointe";
    QString body = "Ceci est un email de test avec une pièce jointe.";
    QString attachment = "test.txt"; //fichier texte à envoyer
    SmtpClient *smtp = new SmtpClient(smtpHost, smtpPort, username, password);

    // Envoi de l'email avec vérification différée

    QTimer::singleShot(3000, [ from, to, subject, body, attachment, &smtp]() {
        smtp->sendEmail(from, to, subject, body, attachment);

        //w.slot_envoyer_massage();
    });

    return a.exec();
}

smtpclient.h

#ifndef SMTPCLIENT_H
#define SMTPCLIENT_H
#include <QSslSocket>
#include <QFile>
#include <QTextStream>
#include <QByteArray>
#include <QFileInfo>
#include <QMimeDatabase>

enum class Step
{
    NONE,
    MAIL_FROM,
    RCPT_TO,
    DATA,
    BODY
};

class SmtpClient : public QObject
{
    Q_OBJECT

public:

    SmtpClient(const QString &host, quint16 port, const QString &username, const QString &password, QObject *parent = nullptr);

    void sendEmail(const QString &from, const QString &to, const QString &subject, const QString &body, const QString &attachmentPath = QString());

private slots:

    void onConnected();
    void onReadyRead();
    void onSslErrors(const QList<QSslError> &errors);
    void onError(QAbstractSocket::SocketError socketError);
    void readServerResponse();

private:

    QSslSocket *socket;
    QString smtpHost;
    quint16 smtpPort;
    QString user;
    QString pass;
    QString emailFrom;
    QString emailTo;
    QString emailSubject;
    QString emailBody;
    QString attachment;
    QByteArray pendingCommand;
    QByteArray serverResponse;

    bool waitingForResponse;
    int expectedResponseCode;

    // Variable membre pour suivre l'étape courante

    Step currentStep = Step::NONE;

    void sendCommand(const QByteArray &command, int expectedCode = 250);
    void handleResponse(const QByteArray &response);
    void startEmailTransmission();
    void sendEmailData();
    void authenticate();

    // méthode pour traiter la réponse

    void processServerResponse(int expectedResponseCode);
};

#endif // SMTPCLIENT_H

smtpclient.cpp

#include "smtpclient.h"
#include <QDebug>

SmtpClient::SmtpClient(
    const QString &host,
    quint16 port,
    const QString &username,
    const QString &password,
    QObject *parent
):
    QObject(parent),
    smtpHost(host),
    smtpPort(port),
    user(username),
    pass(password),
    waitingForResponse(false),
    expectedResponseCode(0)
{
    socket = new QSslSocket(this);
    connect(socket, &QSslSocket::connected, this, &SmtpClient::onConnected);
    connect(socket, &QSslSocket::readyRead, this, &SmtpClient::onReadyRead);
    connect(socket, &QTcpSocket::readyRead, this, &SmtpClient::readServerResponse);
    connect(socket, &QSslSocket::sslErrors, this, &SmtpClient::onSslErrors);
    connect(socket, &QSslSocket::errorOccurred, this, &SmtpClient::onError);
}

void SmtpClient::sendEmail(
    const QString &from,
    const QString &to,
    const QString &subject,
    const QString &body,
    const QString &attachmentPath
) {
    emailFrom = from;
    emailTo = to;
    emailSubject = subject;
    emailBody = body;
    attachment = attachmentPath;
    currentStep = Step::MAIL_FROM; // Initialiser à la première étape
    qDebug() << "Connecting to SMTP server:" << smtpHost << "on port:" << smtpPort;
    socket->connectToHostEncrypted(smtpHost, smtpPort);
}

void SmtpClient::onConnected() {
    qDebug() << "Connected to SMTP server.";
    waitingForResponse = true; // Attente de la réponse initiale `220`
    expectedResponseCode = 220;
}

void SmtpClient::onReadyRead() {
    QByteArray response = socket->readAll();
    qDebug() << "Server response:" << response;
    handleResponse(response);
}

void SmtpClient::onSslErrors(const QList<QSslError> &errors) {
    qDebug() << "SSL Errors occurred:";
    for (const QSslError &error : errors) {
        qDebug() << error.errorString();
    }
    socket->ignoreSslErrors(); // Optionally ignore minor SSL errors
}

void SmtpClient::onError(QAbstractSocket::SocketError socketError) {
    qDebug() << "Socket error:" << socketError;
    qDebug() << "Error details:" << socket->errorString();
}

void SmtpClient::sendCommand(const QByteArray &command, int expectedCode) {
    if (waitingForResponse) {
        qWarning() << "A command is already waiting for a response.";
        return;
    }

    waitingForResponse = true;
    expectedResponseCode = expectedCode;
    pendingCommand = command;
    qDebug() << "Sending command:" << command;
    socket->write(command + "\r\n");
    socket->flush();
}

void SmtpClient::handleResponse(const QByteArray &response) {
    if (!waitingForResponse) {
        qWarning() << "Unexpected response received:" << response;
        return;
    }

    waitingForResponse = false;

    // Parse the response code
    // Les trois premiers caractères sont le code
    QByteArray responseCode = response.mid(0, 3); 
    if (responseCode.toInt() != expectedResponseCode) {
        qWarning() << "Unexpected response code. Expected:"
                   << expectedResponseCode << "Got:" << response;
        socket->disconnectFromHost();
        return;
    }

    // Traitement des réponses valides
    if (expectedResponseCode == 220) {
        sendCommand("EHLO Projet_test_02_Exemple_Qt", 250);
    } else if (expectedResponseCode == 250) {
        if (response.contains("AUTH")) {
            qDebug() << "EHLO successful. Proceeding with authentication.";
            sendCommand("AUTH LOGIN", 334); // On attend une réponse 334 après AUTH LOGIN
        }
    } else if (expectedResponseCode == 334) {
        // Réponse 334 attendue : envoyer l'identifiant ou le mot de passe
        if (response.contains("VXNlcm5hbWU6")) {
            // Serveur demande l'identifiant
            QByteArray usernameEncoded = QByteArray(user.toUtf8()).toBase64();
            // On attend encore une réponse 334 pour le mot de passe
            sendCommand(usernameEncoded, 334); 

        } else if (response.contains("UGFzc3dvcmQ6")) {
            // Serveur demande le mot de passe
            QByteArray passwordEncoded = QByteArray(pass.toUtf8()).toBase64();
            // On attend une réponse 235 pour l'authentification réussie
            sendCommand(passwordEncoded, 235); 
        }
    } else if (expectedResponseCode == 235) {
        qDebug() << "Authentication successful. Proceeding to send email.";
        startEmailTransmission();
    } else if (expectedResponseCode == 354) {
        sendEmailData();
    } else if (expectedResponseCode == 250) {
        if (response.contains("OK") && !emailBody.isEmpty()) {
            qDebug() << "Email sent successfully!";
            socket->disconnectFromHost();
        }
    }
}

void SmtpClient::authenticate() {
    sendCommand("AUTH LOGIN", 334);
    sendCommand(user.toUtf8().toBase64(), 334);
    sendCommand(pass.toUtf8().toBase64(), 235);
}

void SmtpClient::startEmailTransmission() {
    switch (currentStep) {
    case Step::MAIL_FROM:
        currentStep = Step::RCPT_TO; // Passer à l'étape suivante
        sendCommand("MAIL FROM:<" + emailFrom.toUtf8() + ">", 250);
        break;
    case Step::RCPT_TO:
        currentStep = Step::DATA; // Passer à l'étape suivante
        sendCommand("RCPT TO:<" + emailTo.toUtf8() + ">", 250);
        break;
    case Step::DATA:
        currentStep = Step::BODY; // Passer à l'étape suivante
        sendCommand("DATA", 354);
        break;
    case Step::BODY:
        // Ajouter les données de l'email
        sendEmailData();
        currentStep = Step::NONE; // Fin du processus
        break;
    default:
        qWarning() << "Unknown step.";
        break;
    }
}

void SmtpClient::sendEmailData() {
    QByteArray data;
    data.append("From: " + emailFrom.toUtf8() + "\r\n");
    data.append("To: " + emailTo.toUtf8() + "\r\n");
    data.append("Subject: " + emailSubject.toUtf8() + "\r\n");
    data.append("MIME-Version: 1.0\r\n");
    data.append("Content-Type: multipart/mixed; boundary=\"boundary\"\r\n\r\n");

    // Add email body
    data.append("--boundary\r\n");
    data.append("Content-Type: text/plain; charset=\"UTF-8\"\r\n\r\n");
    data.append(emailBody.toUtf8() + "\r\n\r\n");

    // Add attachment if exists
    if (!attachment.isEmpty() && QFile::exists(attachment)) {
        QFile file(attachment);
        if (file.open(QIODevice::ReadOnly)) {
            QByteArray fileData = file.readAll();
            QString mimeType = QMimeDatabase().mimeTypeForFile(attachment).name();
            data.append("--boundary\r\n");
            data.append("Content-Type: " + mimeType.toUtf8() + "\r\n");
            data.append("Content-Disposition: attachment; filename=\"" + QFileInfo(attachment).fileName().toUtf8() + "\"\r\n");
            data.append("Content-Transfer-Encoding: base64\r\n\r\n");
            data.append(fileData.toBase64() + "\r\n");
        }
    }

    data.append("--boundary--\r\n.\r\n");
    sendCommand(data, 250);
}

// Slot pour traiter la réponse

void SmtpClient::readServerResponse() {
    // Lire la réponse du serveur
    if (!socket->isOpen()) {
        qWarning() << "Socket is closed. No data can be read.";
        return;
    }

    qDebug() << "Socket state:" << socket->state();
    QByteArray responseData = socket->readAll();
    qDebug() << "Raw response data:" << responseData;
    serverResponse += responseData;

    while (serverResponse.contains("\r\n")) {
        int endOfLineIndex = serverResponse.indexOf("\r\n");
        QByteArray singleLineResponse = serverResponse.left(endOfLineIndex);
        serverResponse.remove(0, endOfLineIndex + 2);
        qDebug() << "Processed line:" << singleLineResponse;
        // Extraire le code de réponse
        int responseCode = singleLineResponse.left(3).toInt();
        processServerResponse(responseCode);
    }
}

// méthode pour traiter la réponse
void SmtpClient::processServerResponse(int expectedResponseCode) {
    // Vérifiez si la réponse correspond au code attendu
    if (serverResponse.startsWith(QByteArray::number(expectedResponseCode))) {
        switch (currentStep) {
        case Step::MAIL_FROM:
            qDebug() << "Transitioning to RCPT_TO.";
            currentStep = Step::RCPT_TO;
            //sendCommand("RCPT TO:<" + emailTo.toUtf8() + ">", 250);
            startEmailTransmission();
            break;

        case Step::RCPT_TO:
            qDebug() << "Transitioning to DATA.";
            currentStep = Step::DATA;
            sendCommand("DATA", 354);
            break;

        case Step::DATA:
            qDebug() << "Transitioning to BODY.";
            currentStep = Step::BODY;
            sendEmailData();
            break;

        case Step::BODY:
            currentStep = Step::NONE;
            sendCommand("QUIT", 221);
            break;

        default:
            qWarning() << "Unknown step.";
            break;
        }
    } else {
        qWarning() << "Unexpected response received:" << serverResponse;
    }
}

Quand je lance le programme, j'ai les messages suivants dans la console :

Connecting to SMTP server: "smtp.gmail.com" on port: 465
Connected to SMTP server.
Server response: "220 smtp.gmail.com ESMTP ffacd0b85a97d-38bf322b337sm16834709f8f.59 - gsmtp\r\n"
Sending command: "EHLO Projet_test_02_Exemple_Qt"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "250-smtp.gmail.com at your service, [77.131.3.249]\r\n250-SIZE 35882577\r\n250-8BITMIME\r\n250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\r\n250-ENHANCEDSTATUSCODES\r\n250-PIPELINING\r\n250 SMTPUTF8\r\n"
EHLO successful. Proceeding with authentication.
Sending command: "AUTH LOGIN"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "334 VXNlcm5hbWU6\r\n"
Sending command: "bS5tb3VyYWQwMTExQGdtYWlsLmNvbQ=="
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "334 UGFzc3dvcmQ6\r\n"
Sending command: "eXpveiBxcmJ0IGxla2Egamh1dw=="
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "235 2.7.0 Accepted\r\n"
Authentication successful. Proceeding to send email.
Sending command: "MAIL FROM:<xxxxxxxxxxxxxxxxxx@gmail.com>"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "250 2.1.0 OK ffacd0b85a97d-38bf322b337sm16834709f8f.59 - gsmtp\r\n"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""

 Je pense que le soucis vient du slot :

void SmtpClient::readServerResponse() {
    // Lire la réponse du serveur
    if (!socket->isOpen()) {
        qWarning() << "Socket is closed. No data can be read.";
        return;
    }

    qDebug() << "Socket state:" << socket->state();
    QByteArray responseData = socket->readAll();
    qDebug() << "Raw response data:" << responseData;
    serverResponse += responseData;

    while (serverResponse.contains("\r\n")) {
        int endOfLineIndex = serverResponse.indexOf("\r\n");
        QByteArray singleLineResponse = serverResponse.left(endOfLineIndex);
        serverResponse.remove(0, endOfLineIndex + 2);
        qDebug() << "Processed line:" << singleLineResponse;
        // Extraire le code de réponse
        int responseCode = singleLineResponse.left(3).toInt();
        processServerResponse(responseCode);
    }
}

... dans laquelle "QByteArray responseData = socket->readAll();" est toujours nulle, pourtant la socket est ouverte et connectée.Et je n'arrive pas à comprendre pourquoi les réponse serveur s'arrête après

"Sending command: "MAIL FROM:<m.test0111@gmail.com>"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "250 2.1.0 OK ffacd0b85a97d-38bf322b337sm16834709f8f.59 - gsmtp\r\n" ?

Si quelqu'un a une idée s'il vous plaît, ça fait une semaine que je suis bloqué dessus.

Merci d'avance.
Windows / Chrome 131.0.0.0

A voir également:

11 réponses

mamiemando Messages postés 33520 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 5 février 2025 7 823
23 janv. 2025 à 11:38

Bonjour,

Quelques recommandations préalables pour tes futurs messages :

  • Veille dans tes messages à anonymiser les adresses emails / mots de passe (j'ai corrigé ton message initial en conséquence, hormis le mail de test. Définir un #define au bon endroit permettrait de garder la cohérence du programme tout en offusquant l'adresse email / le mot de passe.
  • Je t'invite quand tu fais fasses à un tel bug à copier ton projet et le réduire au minimum pour reproduire le bug. Cela permet de resserrer l'étau, potentiellement localiser l'erreur, et au besoin avoir une question plus concise et plus précise à poser quand tu as recours à un forum
  • Essaye quand tu partages un extrait de code à gérer correctement ton copier coller pour éviter d'avoir une ligne sur deux qui est blanche (j'ai corrigé ton message initial en conséquence)

Retour à ton problème

  • Dans main.cpp, les adresse email from et username que tu utilises ne sont pas cohérentes. C'est peut être juste ça le problème, car gmail va probablement jeter un tel email (notamment pour éviter les attaques par email spoofing).
  • Concernant le reste du code, je suppose qu'il est correct. J'ai l'impression vu que certains commentaires sont en français et d'autres en anglais que tu as récupéré ce code quelque part ? Si oui où ? Je pose la question car si on part du principe que le code original fonctionne, ton erreur se situe dans tes ajouts.

Bonne chance

0
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
23 janv. 2025 à 17:26

Bonjour mamiemando,

Avant tout, merci pour ta réponse.

Pour l'anonymisation, tu as raison. Dans la précipitation, j’ai dû oublier de faire le nécessaire pour les adresses e-mail. Par contre, concernant le mot de passe, je l’ai bien modifié, donc pas de souci de ce côté.

Cela fait plusieurs semaines que j’essaie d’envoyer un e-mail avec C++/Qt. J’ai testé plusieurs bibliothèques, comme cURL, VMime, etc. Finalement, j’ai trouvé un exemple avec Qt dans un livre à la médiathèque, et j’ai essayé de l’adapter à mon cas.

Pour les commentaires dans le code, je préfère les garder en anglais pour me rappeler qu’ils viennent directement du livre. Je sais qu’il reste beaucoup à faire en termes de structuration du code, mais pour l’instant ma priorité est de réussir à envoyer l’e-mail, afin de l’intégrer dans une application de gestion de magasin. Cela permettra d’envoyer les factures par e-mail.

Retour au problème :

  1. Quand tu dis : "Dans main.cpp, les adresses e-mail from et username que tu utilises ne sont pas cohérentes."

    • Peux-tu préciser pourquoi ? Si tu parles de l’intitulé, c’est parce que j’ai modifié les adresses pour le message.
  2. Voici les messages de retour :

Connecting to SMTP server: "smtp.gmail.com" on port: 465
Connected to SMTP server.
Server response: "220 smtp.gmail.com ESMTP ffacd0b85a97d-38c2a17d5d4sm64480f8f.21 - gsmtp\r\n"
Sending command: "EHLO Projet_test_02_Exemple_Qt"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "250-smtp.gmail.com at your service, [77.131.3.129]\r\n250-SIZE 35882577\r\n250-8BITMIME\r\n250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\r\n250-ENHANCEDSTATUSCODES\r\n250-PIPELINING\r\n250 SMTPUTF8\r\n"
EHLO successful. Proceeding with authentication.
Sending command: "AUTH LOGIN"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "334 VXNlcm5hbWU6\r\n"
Sending command: "bS5tb3VyYWQwMTExQGdtYWlsLmNvbQ=="
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "334 UGFzc3dvcmQ6\r\n"
Sending command: "eXpveiBxcmJ0IGxla2Egamh1dw=="
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "235 2.7.0 Accepted\r\n"
Authentication successful. Proceeding to send email.
Sending command: "MAIL FROM:<m.mourad0111@gmail.com>"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "250 2.1.0 OK ffacd0b85a97d-38c2a17d5d4sm64480f8f.21 - gsmtp\r\n"
Socket state: QAbstractSocket::ConnectedState
Raw response data: 

et au bout de quelques minutes, voici la suite des messages

Server response: "451-4.4.2 Timeout - closing connection.\r\n451-4.4.2  For more information, go to\r\n451 4.4.2  https://support.google.com/a/answer/3221692 ffacd0b85a97d-38c2a17d5d4sm64480f8f.21 - gsmtp\r\n"
Unexpected response received: "451-4.4.2 Timeout - closing connection.\r\n451-4.4.2  For more information, go to\r\n451 4.4.2  https://support.google.com/a/answer/3221692 ffacd0b85a97d-38c2a17d5d4sm64480f8f.21 - gsmtp\r\n"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Socket error: QAbstractSocket::RemoteHostClosedError
Error details: "The TLS/SSL connection has been closed"
Socket error: QAbstractSocket::RemoteHostClosedError
Error details: "The remote host closed the connection"

et je n'arrive pas à comprendre pourquoi?

0
mamiemando Messages postés 33520 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 5 février 2025 7 823
23 janv. 2025 à 18:29

En réponse à #3. Eh bien tu as écris :

QString username = QString("m. test111@gmail.com");
QString from =             "m.test111@gmail.com";

... comme tu le vois un espace s'est glissé dans la variable username.

0
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
25 janv. 2025 à 16:36

Non en fait, c'est dans le message que j'ai essayé de modifier mon adresse email, et c'est juste une erreur de frappe, dans le code j'utilise ma vrai adresse email et elle est juste.

0
mamiemando Messages postés 33520 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 5 février 2025 7 823
27 janv. 2025 à 12:21

Dans #3 on voit que :

  • Du côté du serveur gmail un timeout a été déclenché (ce qui semble signifie que le serveur attendait quelque chose qu'il n'a jamais reçu. Y a t'il une authentification renforcée ?
  • Le message d'erreur mentionne un lien (mais qui semble mal reporté dans ton message). Quel est ce lien ? Que dit-il ?

Bonne chance

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
27 janv. 2025 à 17:24

Oui j'ai activé la double identification sur gmail. et c'est bien le mot de passe application que j'envoie.

0
mamiemando Messages postés 33520 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 5 février 2025 7 823
28 janv. 2025 à 18:41

Dans ce cas, est-ce que le serveur gmail n'attend pas simplement le code PIN inhérent au MFA ?

0
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
30 janv. 2025 à 16:12

Bonjour mamiemando,

En fait la double identification de Gmail je l'ai utilisée avec curl et c'est juste d'envoyer le mot de passe application généré par Gmail et non le mdp du compte Gmail. et ça marchait très bien, mais là je ne comprends pas ce qu'il attend. en plus il n'y a pas de code PIN avec Gmail.

0
mamiemando Messages postés 33520 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 5 février 2025 7 823
31 janv. 2025 à 11:41

Est-ce qu'on peut imaginer désactiver le MFA temporairement pour voir si ça vient de là ? Car comme toi, je ne sais pas ce qu'attend ton serveur gmail.

0
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
Modifié le 31 janv. 2025 à 19:12

Non ça ne vient pas de là., j'ai permuté les 2 email gmail, parce que j'utilise 2 email de gmail pour les tests, donc j'ai utilisé l'email où je n'ai pas activé la double identification pour l'envoie et l'autre pour la réception et voici les messages de retour

Connecting to SMTP server: "smtp.gmail.com" on port: 465
Connected to SMTP server.
Server response: "220 smtp.gmail.com ESMTP 5b1f17b1804b1-438dcc2f73asm96633865e9.24 - gsmtp\r\n"
Sending command: "EHLO Projet_test_02_Exemple_Qt"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "250-smtp.gmail.com at your service, [77.130.249.242]\r\n250-SIZE 35882577\r\n250-8BITMIME\r\n250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\r\n250-ENHANCEDSTATUSCODES\r\n250-PIPELINING\r\n250 SMTPUTF8\r\n"
EHLO successful. Proceeding with authentication.
Sending command: "AUTH LOGIN"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "334 VXNlcm5hbWU6\r\n"
Sending command: "bW9oYWtlc3NAZ21haWwuY29t"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "334 UGFzc3dvcmQ6\r\n"
Sending command: "R2FtZWJvb3N0ZXIyMDI0"
Socket state: QAbstractSocket::ConnectedState
Raw response data: ""
Server response: "535-5.7.8 Username and Password not accepted. For more information, go to\r\n535 5.7.8  https://support.google.com/mail/?p=BadCredentials 5b1f17b1804b1-438dcc2f73asm96633865e9.24 - gsmtp\r\n"
Unexpected response code. Expected: 235 Got: "535-5.7.8 Username and Password not accepted. For more information, go to\r\n535 5.7.8  https://support.google.com/mail/?p=BadCredentials 5b1f17b1804b1-438dcc2f73asm96633865e9.24 - gsmtp\r\n"
Socket state: QAbstractSocket::ClosingState
Raw response data: ""

je pense qu'il faut mettre l'accent sur cette partie du message 

Server response: "535-5.7.8 Username and Password not accepted. For more information, go to\r\n535 5.7.8  https://support.google.com/mail/?p=BadCredentials 5b1f17b1804b1-438dcc2f73asm96633865e9.24 - gsmtp\r\n"
Unexpected response code. Expected: 235 Got: "535-5.7.8 Username and Password not accepted. For more information, go to\r\n535 5.7.8  https://support.google.com/mail/?p=BadCredentials 5b1f17b1804b1-438dcc2f73asm96633865e9.24 - gsmtp\r\n"
0
mamiemando Messages postés 33520 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 5 février 2025 7 823
31 janv. 2025 à 19:14

Le message d'erreur semble suggérer que le login / mot de passe sont incorrects. Es-tu sûr de toi ? Le lien du message d'erreur mène notamment à cette page. As-tu tout vérifié ?

0
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
1 févr. 2025 à 16:42

Demain je reviendrai sur curl et je vous tiendrai au courant.

0
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
Modifié le 4 févr. 2025 à 15:18

Bonjour à tous,

Je reviens sur l'utilisation de curl. J'ai ajouté un projet Qt simple 6.8 et ça se passe très bien avec curl. Mais les erreurs sont dues à des conflits de définition du type byte entre les en-têtes système de Windows et la bibliothèque standard C++ (std::byte introduit en C++17). J'ai une application de gestion de magasin, et dans la partie facturation, j'ai une classe avec interface Qt avec les fichiers suivants
"fen_de_facturation.h" , "fen_de_facturation.cpp" et "fen_de_facturation.ui"
Jusqu'au là tout fonctionne normalement.
Maintenant j'ai rajouté un Bouton sur l'interface "fen_de_facturation.ui" pour pouvoir envoyer un email, que j'ai relier à un slot "
voici le slot "SlotEnvoyerEmail()"
 

int Fen_De_Facturation::SlotEnvoyerEmail()
{


    ClsLibCurlModifiee *objClsLibCurlModifiee = new ClsLibCurlModifiee();
    //****************************************************
    objClsLibCurlModifiee->setStrFROM_ADDR("m.mourad0111@gmail.com");
    objClsLibCurlModifiee->setStrTO_ADDR("moakss@gmail.com");
    objClsLibCurlModifiee->setStrCC_ADDR("mohkes@outlook.com");
    objClsLibCurlModifiee->setStrNomPourCorespondance("Magasin Solectrom");
    objClsLibCurlModifiee->setStrSujetEmail("Votre facture Solectrom");
    objClsLibCurlModifiee->setStrUserName("m.mouad0111@gmail.com");
    objClsLibCurlModifiee->setStrPassWord("yoz qbt leka jhuw");
    objClsLibCurlModifiee->setStrSmtpMailPort("smtp://smtp.gmail.com:587");
    objClsLibCurlModifiee->setStrCertPath( "C:/Data/Fichiers_applications/C++/LibrairiesExternes/Certificats/cacert.pem-master/cacert.pem");
    objClsLibCurlModifiee->setStrFilePath("C:/Data/Fichiers_applications/C++/Projets_QtCreator/Tests/testCurlConsole/testCurlConsole/facture.pdf");

    objClsLibCurlModifiee->setStrMessage(" Bonjour,\r\n"
                                         "\r\n"
                                         "Vous trouverez ci-joint à ce message votre facture chez SOLECTROM.\r\n"
                                         "Votre magasin Solectrom\r\n"
                                         "\r\n");

    //objClsLibCurlModifiee->setParametres();

    if (objClsLibCurlModifiee->setParametres() != CURLE_OK) {
         qDebug() << "Failed to configure CURL" << Qt::endl;
        return;
    }

    std::vector<std::string> files = {
        "C:/Data/Fichiers_applications/C++/Projets_QtCreator/Tests/testCurlConsole/testCurlConsole/facture1.pdf",
        "C:/Data/Fichiers_applications/C++/Projets_QtCreator/Tests/testCurlConsole/testCurlConsole/facture2.pdf"
    };

    objClsLibCurlModifiee->setStrFileNameApearInTheEmail("facture88.pdf");
    for (const auto& file : files)
    {
        if (objClsLibCurlModifiee->sendEmail(file, objClsLibCurlModifiee->getStrFileNameApearInTheEmail().c_str()) != CURLE_OK)
        {
            qDebug() << "Failed to send email with file: " << file << Qt::endl;
        }
        else
        {
            qDebug() << "Email sent with file: " << file << Qt::endl;
        }
    }

    delete objClsLibCurlModifiee;

}

En ce qui concerne Curl j'ai créé les 2 fichiers suivants qui contiennent la classe "ClsLibCurlModifiee"

voici le "libcurlmodifiee.h"

#ifndef LIBCURLMODIFIEE_H
#define LIBCURLMODIFIEE_H


#include <curl/curl.h>
#include <string>

class ClsLibCurlModifiee
{
       public:
           /***********************************************************************************
            * ******************************* Les méthodes publiques  *****************************
            * *********************************************************************************/
           //Constructeur
           ClsLibCurlModifiee();
           //Déstructeur
           ~ClsLibCurlModifiee();
           //Fonction pour recupérer la date d'aujourd'hui
           std::string getCurrentDate();

           std::string createPayloadText();

           //Fonction qui vérifie si un fichier existe
           bool fileExists(const std::string& path);

           //Fonction pour lire un fichier
           std::string readFile(const std::string& filePath);

           //Fonction pour configurer les options
           int setParametres();

           int sendEmail(const std::string& filePath, const std::string& fileName);


           /***********************************************************************************
            * ******************************* Les getters et les Setters ****************************
            * *********************************************************************************/

           //Getter et setter de "StrFROM_ADDR"
           std::string getStrFROM_ADDR() const;
           void setStrFROM_ADDR(const std::string &newStrFROM_ADDR);

           //Getter et setter de "StrTO_ADDR"
           std::string getStrTO_ADDR() const;
           void setStrTO_ADDR(const std::string &newStrTO_ADDR);

           //Getter et setter de "StrCC_ADDR"
           std::string getStrCC_ADDR() const;
           void setStrCC_ADDR(const std::string &newStrCC_ADDR);

           //Getter et setter de "StrFROM_MAIL"
           std::string getStrFROM_MAIL() const;
           void setStrFROM_MAIL(const std::string &newStrFROM_MAIL);

           //Getter et setter de "StrTO_MAIL"
           std::string getStrTO_MAIL() const;
           void setStrTO_MAIL(const std::string &newStrTO_MAIL);

           //Getter et setter de "StrCC_MAIL"
           std::string getStrCC_MAIL() const;
           void setStrCC_MAIL(const std::string &newStrCC_MAIL);

           //Getter et setter de "StrCertPath" chemin du certificat
           std::string getStrCertPath() const;
           void setStrCertPath(const std::string &newStrCertPath);

           //Getter et setter de "StrFiletPath" chemin du fichier à envoyé
           std::string getStrFilePath() const;
           void setStrFilePath(const std::string &newStrFiletPath);

           //Getter et setter de "StrSujetEmail" sujet de l'email
           std::string getStrSujetEmail() const;
           void setStrSujetEmail(const std::string &newStrSujetEmail);

           //Getter et setter de "StrFileNameApearInTheEmail" Le nom de la piece jointe qui apparaitera dans l'email
           std::string getStrFileNameApearInTheEmail() const;
           void setStrFileNameApearInTheEmail(const std::string &newStrFileNameApearInTheEmail);

           //Getter et setter de "StrUserName" Le nom d'utilisateur
           std::string getStrUserName() const;
           void setStrUserName(const std::string &newStrUserName);

           //Getter et setter de "StrPassWord" Le mot de passe utilisateur
           std::string getStrPassWord() const;
           void setStrPassWord(const std::string &newStrPassWord);

           //Getter et setter de "StrSmtpMailPort" Le SMTP et le port utilisé
           std::string getStrSmtpMailPort() const;
           void setStrSmtpMailPort(const std::string &newStrSmtpMailPort);

           //Getter et setter de "StrNomPourCorespondance" Le nom affiché dans la rubrique correspondant
           std::string getStrNomPourCorespondance() const;
           void setStrNomPourCorespondance(const std::string &newStrNomPourCorespondance);

           //Getter et setter de "StrMessage" contient le message de l'email tout simplement.
           std::string getStrMessage() const;
           void setStrMessage(const std::string &newStrMessage);

       private:
           CURL *curl;
           CURLcode res = CURLE_OK;
           struct curl_slist *recipients = NULL;
           struct curl_slist *headers = NULL;

           std::string StrFROM_ADDR; //    
           std::string StrTO_ADDR  ; //    
           std::string StrCC_ADDR; //      

           std::string StrFROM_MAIL; // 
           std::string StrTO_MAIL ; //  
           std::string StrCC_MAIL ; //  

           std::string StrCertPath; //Certificat
           std::string StrFilePath; //Fichier à envoyé
           std::string StrSujetEmail; //Le sujet de l'email
           std::string StrFileNameApearInTheEmail; //Le nom de la piece jointe qui apparaitera dans l'email

           std::string StrUserName; // 
           std::string StrPassWord; // "************" le mot de passe
           std::string StrSmtpMailPort; //Contient le SMTP et le port utilisé (smtp://smtp.gmail.com:587)
           std::string StrNomPourCorespondance; //C'est le nom qui sera affiché dans la liste des email dans la rubrique corespondant, chez le client
           std::string StrMessage; //Le message de l'email

};

#endif // LIBCURLMODIFIEE_H

et voici "libcurlmodifiee.cpp"

#include "libcurlmodifiee.h"

// Le constructeur
ClsLibCurlModifiee::ClsLibCurlModifiee()
{
           curl = curl_easy_init();
}

// Le destructeur
ClsLibCurlModifiee::~ClsLibCurlModifiee()
{
           if (curl) {
                      curl_easy_cleanup(curl);
           }
}

// Fonction pour récupérer la date d'aujourd'hui
std::string ClsLibCurlModifiee::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 ClsLibCurlModifiee::createPayloadText() {
           std::ostringstream ss;
           ss << getStrMessage().c_str();
           // ss << "Bonjour,\r\n"
           //    << "\r\n"
           //    << "Vous trouverez ci-joint à ce message votre facture chez SOLECTROM.\r\n"
           //    << "Votre magasin Solectrom\r\n";
           return ss.str();
}

// Fonction qui vérifie si un fichier existe
bool ClsLibCurlModifiee::fileExists(const std::string& path) {
           std::ifstream file(path);
           return file.good();
}

// Fonction pour lire un fichier
std::string ClsLibCurlModifiee::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();
}

// Fonction de configuration Curl
int ClsLibCurlModifiee::setParametres()
{
           if (!curl) return CURLE_FAILED_INIT;

           //const char *ca_cert_path = "C:/Data/Fichiers_applications/C++/LibrairiesExternes/Certificats/cacert.pem-master/cacert.pem";

           if (!fileExists(getStrCertPath().c_str()))
           {
                      std::cerr << "Certificate file not found at " << getStrCertPath().c_str() << std::endl;
                      return 1;
           }
           else
           {
                      std::cerr << "Certificate file found at " << getStrCertPath().c_str() << std::endl;
           }

           setStrFROM_MAIL("Sender Person <" + getStrFROM_ADDR() +  ">");
           setStrTO_MAIL(getStrNomPourCorespondance() + " <" + getStrFROM_ADDR() + ">");
           std::string str = getStrNomPourCorespondance() + " <" + getStrFROM_ADDR() + ">";
           setStrCC_MAIL("John CC Smith <" + getStrCC_MAIL() +  ">");

           curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
           curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //(0L : pour ne pas utiliser le certificat), (1L : pour l'utilisé)
           curl_easy_setopt(curl, CURLOPT_CAPATH, getStrCertPath().c_str());

           curl_easy_setopt(curl, CURLOPT_URL, getStrSmtpMailPort().c_str());
           curl_easy_setopt(curl, CURLOPT_MAIL_FROM, getStrFROM_ADDR().c_str());

           recipients = curl_slist_append(recipients, getStrTO_ADDR().c_str());
           recipients = curl_slist_append(recipients, getStrCC_ADDR().c_str());
           curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);

           // Set the headers
           headers = curl_slist_append(headers, ("Date: " + getCurrentDate()).c_str());

           std::string fromMailHeader = "From: " + getStrFROM_MAIL();
           headers = curl_slist_append(headers, fromMailHeader.c_str());

           std::string toHeader = "To: " + getStrTO_MAIL();
           headers = curl_slist_append(headers, toHeader.c_str());

           std::string strCcMailHeader = "Cc: " + getStrCC_MAIL();
           headers = curl_slist_append(headers, strCcMailHeader.c_str());

           headers = curl_slist_append(headers, "Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>");

           std::string strSujetMailHeader = "Subject: " + getStrSujetEmail();
           headers = curl_slist_append(headers, strSujetMailHeader.c_str());
           curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

           curl_easy_setopt(curl, CURLOPT_USERNAME, getStrUserName().c_str());
           curl_easy_setopt(curl, CURLOPT_PASSWORD, getStrPassWord().c_str()); // Remplacez par votre mot de passe d'application Gmail

           curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);



           return CURLE_OK;
}

// Fonction d'envoi d'email
int ClsLibCurlModifiee::sendEmail(const std::string& filePath, const std::string& fileName)
{

           if (!curl) return CURLE_FAILED_INIT;

           if (!fileExists(filePath)) {
                      std::cerr << "File not found at " << filePath << std::endl;
                      return 3;
           }

           std::string fileContent = readFile(filePath);

           // Create the MIME structure
           curl_mime *mime = curl_mime_init(curl);
           curl_mimepart *part;

           // 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");

           // Add the attachment part
           part = curl_mime_addpart(mime);
           curl_mime_data(part, fileContent.c_str(), fileContent.size());
           curl_mime_filename(part, fileName.c_str());
           curl_mime_type(part, "application/pdf");
           curl_mime_encoder(part, "base64");

           // Set the MIME structure
           curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);



           CURLcode res = curl_easy_perform(curl);

           curl_mime_free(mime);

           if (res != CURLE_OK) {
                      fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
                      return res;
           }

           return CURLE_OK;
}


//Getter et setter de "StrFROM_ADDR"
std::string ClsLibCurlModifiee::getStrFROM_ADDR() const
{
           return StrFROM_ADDR;
}
void ClsLibCurlModifiee::setStrFROM_ADDR(const std::string &newStrFROM_ADDR)
{
           StrFROM_ADDR = newStrFROM_ADDR;
}

//Getter et setter de "StrTO_ADDR"
std::string ClsLibCurlModifiee::getStrTO_ADDR() const
{
           return StrTO_ADDR;
}
void ClsLibCurlModifiee::setStrTO_ADDR(const std::string &newStrTO_ADDR)
{
           StrTO_ADDR = newStrTO_ADDR;
}

//Getter et setter de "StrCC_ADDR"
std::string ClsLibCurlModifiee::getStrCC_ADDR() const
{
           return StrCC_ADDR;
}
void ClsLibCurlModifiee::setStrCC_ADDR(const std::string &newStrCC_ADDR)
{
           StrCC_ADDR = newStrCC_ADDR;
}

//Getter et setter de "StrFROM_MAIL"
std::string ClsLibCurlModifiee::getStrFROM_MAIL() const
{
           return StrFROM_MAIL;
}
void ClsLibCurlModifiee::setStrFROM_MAIL(const std::string &newStrFROM_MAIL)
{
           StrFROM_MAIL = newStrFROM_MAIL;
}

//Getter et setter de "StrTO_MAIL"
std::string ClsLibCurlModifiee::getStrTO_MAIL() const
{
           return StrTO_MAIL;
}
void ClsLibCurlModifiee::setStrTO_MAIL(const std::string &newStrTO_MAIL)
{
           StrTO_MAIL = newStrTO_MAIL;
}

//Getter et setter de "StrCC_MAIL"
std::string ClsLibCurlModifiee::getStrCC_MAIL() const
{
           return StrCC_MAIL;
}
void ClsLibCurlModifiee::setStrCC_MAIL(const std::string &newStrCC_MAIL)
{
           StrCC_MAIL = newStrCC_MAIL;
}

//Getter et setter de "StrCertPath" chemin du certificat
std::string ClsLibCurlModifiee::getStrCertPath() const
{
           return StrCertPath;
}

void ClsLibCurlModifiee::setStrCertPath(const std::string &newStrCertPath)
{
           StrCertPath = newStrCertPath;
}

//Getter et setter de "StrFiletPath" chemin du fichier à envoyé
std::string ClsLibCurlModifiee::getStrFilePath() const
{
           return StrFilePath;
}

void ClsLibCurlModifiee::setStrFilePath(const std::string &newStrFilePath)
{
           StrFilePath = newStrFilePath;
}

//Getter et setter de "StrSujetEmail" sujet de l'email
std::string ClsLibCurlModifiee::getStrSujetEmail() const
{
           return StrSujetEmail;
}
void ClsLibCurlModifiee::setStrSujetEmail(const std::string &newStrSujetEmail)
{
           StrSujetEmail = newStrSujetEmail;
}

//Getter et setter de "StrFileNameApearInTheEmail" Le nom de la piece jointe qui apparaitera dans l'email
std::string ClsLibCurlModifiee::getStrFileNameApearInTheEmail() const
{
           return StrFileNameApearInTheEmail;
}
void ClsLibCurlModifiee::setStrFileNameApearInTheEmail(const std::string &newStrFileNameApearInTheEmail)
{
           StrFileNameApearInTheEmail = newStrFileNameApearInTheEmail;
}

//Getter et setter de "StrUserName" Le nom d'utilisateur
std::string ClsLibCurlModifiee::getStrUserName() const
{
           return StrUserName;
}
void ClsLibCurlModifiee::setStrUserName(const std::string &newStrUserName)
{
           StrUserName = newStrUserName;
}

//Getter et setter de "StrPassWord" Le mot de passe utilisateur
std::string ClsLibCurlModifiee::getStrPassWord() const
{
           return StrPassWord;
}
void ClsLibCurlModifiee::setStrPassWord(const std::string &newStrPassWord)
{
           StrPassWord = newStrPassWord;
}

//Getter et setter de "StrSmtpMailPort" Le SMTP et le port utilisé
std::string ClsLibCurlModifiee::getStrSmtpMailPort() const
{
           return StrSmtpMailPort;
}
void ClsLibCurlModifiee::setStrSmtpMailPort(const std::string &newStrSmtpMailPort)
{
           StrSmtpMailPort = newStrSmtpMailPort;
}

//Getter et setter de "StrNomPourCorespondance" Le nom affiché dans la rubrique correspondant
std::string ClsLibCurlModifiee::getStrNomPourCorespondance() const
{
           return StrNomPourCorespondance;
}
void ClsLibCurlModifiee::setStrNomPourCorespondance(const std::string &newStrNomPourCorespondance)
{
           StrNomPourCorespondance = newStrNomPourCorespondance;
}

//Getter et setter de "StrMessage" contient le message de l'email tout simplement.
std::string ClsLibCurlModifiee::getStrMessage() const
{
           return StrMessage;
}
void ClsLibCurlModifiee::setStrMessage(const std::string &newStrMessage)
{
           StrMessage = newStrMessage;
}


Je l'ai ajouté au projet, j'ai tout recompilé et ça se passe très bien.

Ensuite, pour pouvoir utiliser la classe curl dans mon slot "SlotEnvoyerEmail()"
je l'ai inclus dans le fichier "fen_de_facturation.h"

#include "../Administration/libcurlmodifiee.h

qui lui-même inclue le fichier <curl/curl.h> :

#include <curl/curl.h>

Et voici le fichier "curl/curl.h", ou du moins les parties où il y a les inclusions de fichiers

#ifndef CURLINC_CURL_H
#define CURLINC_CURL_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * SPDX-License-Identifier: curl
 *
 ***************************************************************************/

/*
 * If you have libcurl problems, all docs and details are found here:
 *   https://curl.se/libcurl/
 */

#ifdef CURL_NO_OLDIES
#define CURL_STRICTER
#endif

/* Compile-time deprecation macros. */
#if defined(__GNUC__) &&                                                \
  ((__GNUC__ > 12) || ((__GNUC__ == 12) && (__GNUC_MINOR__ >= 1 ))) &&  \
  !defined(__INTEL_COMPILER) &&                                         \
  !defined(CURL_DISABLE_DEPRECATION) && !defined(BUILDING_LIBCURL)
#define CURL_DEPRECATED(version, message)                       \
  __attribute__((deprecated("since " # version ". " message)))
#define CURL_IGNORE_DEPRECATION(statements) \
      _Pragma("GCC diagnostic push") \
      _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \
      statements \
      _Pragma("GCC diagnostic pop")
#else
#define CURL_DEPRECATED(version, message)
#define CURL_IGNORE_DEPRECATION(statements)     statements
#endif

#include "curlver.h"         /* libcurl version defines   */

#include "system.h"          /* determine things run-time */



#include <stdio.h>
#include <limits.h>

#if defined(__FreeBSD__) || defined(__MidnightBSD__)
/* Needed for __FreeBSD_version or __MidnightBSD_version symbol definition */
#include <sys/param.h>
#endif

/* The include stuff here below is mainly for time_t! */
#include <sys/types.h>
#include <time.h>

#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
      defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
/* The check above prevents the winsock2 inclusion if winsock.h already was
   included, since they can't co-exist without problems */
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#endif

/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
   libc5-based Linux systems. Only include it on systems that are known to
   require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
    defined(__minix) || defined(__INTEGRITY) || \
    defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
    defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \
   (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \
   (defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \
    defined(__sun__) || defined(__serenity__) || defined(__vxworks__)
#include <sys/select.h>
#endif

#if !defined(_WIN32) && !defined(_WIN32_WCE)
#include <sys/socket.h>
#endif

#if !defined(_WIN32)
#include <sys/time.h>
#endif

/* Compatibility for non-Clang compilers */
#ifndef __has_declspec_attribute
#  define __has_declspec_attribute(x) 0
#endif

#ifdef  __cplusplus
extern "C" {
#endif

#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
typedef struct Curl_easy CURL;
typedef struct Curl_share CURLSH;
#else
typedef void CURL;
typedef void CURLSH;
#endif

/*
 * libcurl external API function linkage decorations.
 */

#ifdef CURL_STATICLIB
#  define CURL_EXTERN
#elif defined(_WIN32) || \
     (__has_declspec_attribute(dllexport) && \
      __has_declspec_attribute(dllimport))
#  if defined(BUILDING_LIBCURL)
#    define CURL_EXTERN  __declspec(dllexport)
#  else
#    define CURL_EXTERN  __declspec(dllimport)
#  endif
#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS)
#  define CURL_EXTERN CURL_EXTERN_SYMBOL
#else
#  define CURL_EXTERN
#endif

et voici la fin du fichier curl.h

/* unfortunately, the easy.h and multi.h include files need options and info
  stuff before they can be included! */
#include "easy.h" /* nothing in curl is fun without the easy stuff */
#include "multi.h"
#include "urlapi.h"
#include "options.h"
#include "header.h"
#include "websockets.h"
#include "mprintf.h"

/* the typechecker doesn't work in C++ (yet) */
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
    ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
    !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
#include "typecheck-gcc.h"
#else
#if defined(__STDC__) && (__STDC__ >= 1)
/* This preprocessor magic that replaces a call with the exact same call is
   only done to make sure application authors pass exactly three arguments
   to these functions. */
#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
#endif /* __STDC__ >= 1 */
#endif /* gcc >= 4.3 && !__cplusplus && !CURL_DISABLE_TYPECHECK */

#endif /* CURLINC_CURL_H */

et là quand je compile j'ai les erreurs suivantes

C:\Qt\Tools\mingw1310_64\x86_64-w64-mingw32\include\rpcndr.h:64: erreur : reference to 'byte' is ambiguous
In file included from C:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include/wtypes.h:8,
                 from C:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include/winscard.h:10,
                 from C:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include/windows.h:97,
                 from C:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include/winsock2.h:23,
                 from C:/Data/Fichiers_applications/C++/LibrairiesExternes/curl-8.8.0_1-win64-mingw/include/curl/curl.h:76,
                 from ..\..\Facturation/../Administration/libcurlmodifiee.h:8,
                 from ..\..\Facturation/fen_de_facturation.h:34,
                 from ..\..\fenprincipalegestion.h:34,
                 from ..\..\main.cpp:3:
C:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include/rpcndr.h:64:11: error: reference to 'byte' is ambiguous
   64 |   typedef byte cs_byte;
      |           ^~~~

C:\Qt\Tools\mingw1310_64\x86_64-w64-mingw32\include\wtypesbase.h:349: erreur : reference to 'byte' is ambiguous
C:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include/wtypesbase.h:349:5: error: reference to 'byte' is ambiguous
  349 |     byte abData[1];
      |     ^~~~
C:/Qt/Tools/mingw1310_64/lib/gcc/x86_64-w64-mingw32/13.1.0/include/c++/cstddef:69:14: note: candidates are: 'enum class std::byte'
   69 |   enum class byte : unsigned char {};
      |              ^~~~
C:/Qt/Tools/mingw1310_64/x86_64-w64-mingw32/include/rpcndr.h:63:25: note:                 'typedef unsigned char byte'
   63 |   typedef unsigned char byte;
      |                         ^~~~

Je n'ai mis que quelques erreurs, mais il y en a un cinquantaine, et je sais pas comment contourner cette erreur.

Merci d'avance pour votre aide

0
mamiemando Messages postés 33520 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 5 février 2025 7 823
Modifié le 4 févr. 2025 à 15:23

Bonjour

  • Quelque chose m'échappe. Quel rapport avec ton problème avec "QSslSocket" et "curl" ?
  • Comme dit ici il y a probablement une collision entre le type "byte" et "std::byte" ce qui suggère une utilisation abusive dans un header de "using namespace std;".
    • Supprimer cette(ces) directive(s) aux endroits inappropriés devrait résoudre le problème.
    • Le lien que je cite recommande aussi de compiler avec l'option "-std=gnu++14" (je ne pense pas que ce soit nécessaire, mais ça ne coûte rien d'utiliser).

Bonne chance

0
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
4 févr. 2025 à 17:59

Bonjour mamiemando,

Merci pour ton aide et tes conseils, ils étaient vraiment bénéfiques et c'est vrai que c'est juste un using namespace std  en trop qui causait problème, maintenant ça fonctionne très bien. et j'arrive à envoyer des emails avec pièce jointe.

0
mamiemando Messages postés 33520 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 5 février 2025 7 823
5 févr. 2025 à 01:58

Félicitations @Mourad2009B StatutMembre. :-)

  • Merci de résumer dans un message le lien entre l'envoi d'email, curl, et la cause des erreurs SMTP. Ça aidera sans doute les personnes qui tomberont sur cette discussion.
  • Merci de basculer ton sujet en résolu.
0
Mourad2009B Messages postés 118 Date d'inscription lundi 23 août 2010 Statut Membre Dernière intervention 5 février 2025
5 févr. 2025 à 18:27

Ok je ferai ça demain et je mettrai le sujet en résolu. Merci encore

0