Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Can't send file via SMTP protocol
Qt 6.11 is out! See what's new in the release blog

Can't send file via SMTP protocol

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 5 Posters 1.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ JonB

    @razorqhex
    That is not adding error handling, and does not tell us for sure what the situation is. You should follow @jsulm's suggestion.

    R Offline
    R Offline
    razorqhex
    wrote on last edited by razorqhex
    #6

    @JonB, I wrote an error handler and this is what it outputs.
    Снимок экрана 2023-03-24 в 10.29.00.png

    It seems to me that the problem is in this block of code:

            QByteArray boundary = "boundary_12345";
    	QByteArray messageData;
    	messageData.append("From: <YOUR_MAIL>\r\n");
    	messageData.append(QString("To: <%1>\r\n").arg(ui->lEdit_addrFrom->text()).toUtf8());
    	messageData.append(QString("Subject: %1\r\n").arg(subject).toUtf8());
    	messageData.append("\r\n");
    	messageData.append(QString(body).toUtf8() + "\r\n.\r\n");
    	messageData.append(QString("Content-Type: multipart/mixed; boundary=%1\r\n").arg(boundary).toUtf8());
    	messageData.append("\r\n");
    	messageData.append(QString("--%1\r\n").arg(boundary).toUtf8());
    	messageData.append("Content-Type: text/plain\r\n");
    	messageData.append("\r\n");
    	messageData.append(body.toUtf8());
    	messageData.append("\r\n");
    	messageData.append(QString("--%1\r\n").arg(boundary).toUtf8());
    	messageData.append(QString("Content-Disposition: attachment; filename=\"%1\"\r\n").arg(QFileInfo(fileName).fileName()).toUtf8());
    	messageData.append(QString("Content-Type: %1\r\n").arg(mime.name()).toUtf8());
    	messageData.append("Content-Transfer-Encoding: base64\r\n");
    	messageData.append("\r\n");
    	socket.flush();
    	messageData.append(fileData.toBase64());
    	messageData.append("\r\n");
    	messageData.append(QString("--%1--\r\n").arg(boundary).toUtf8());
    	socket.write(messageData);
    	socket.flush();
    

    But I don't know exactly what the problem is.

    C 1 Reply Last reply
    0
    • jsulmJ jsulm

      @razorqhex You should add error handling. For example connect a slot to
      https://doc.qt.io/qt-6/qabstractsocket.html#errorOccurred and print out the error.

      R Offline
      R Offline
      razorqhex
      wrote on last edited by
      #7

      @jsulm, Hello. I connected an error handler and wrote the debugger output above

      1 Reply Last reply
      0
      • R razorqhex

        @JonB, I wrote an error handler and this is what it outputs.
        Снимок экрана 2023-03-24 в 10.29.00.png

        It seems to me that the problem is in this block of code:

                QByteArray boundary = "boundary_12345";
        	QByteArray messageData;
        	messageData.append("From: <YOUR_MAIL>\r\n");
        	messageData.append(QString("To: <%1>\r\n").arg(ui->lEdit_addrFrom->text()).toUtf8());
        	messageData.append(QString("Subject: %1\r\n").arg(subject).toUtf8());
        	messageData.append("\r\n");
        	messageData.append(QString(body).toUtf8() + "\r\n.\r\n");
        	messageData.append(QString("Content-Type: multipart/mixed; boundary=%1\r\n").arg(boundary).toUtf8());
        	messageData.append("\r\n");
        	messageData.append(QString("--%1\r\n").arg(boundary).toUtf8());
        	messageData.append("Content-Type: text/plain\r\n");
        	messageData.append("\r\n");
        	messageData.append(body.toUtf8());
        	messageData.append("\r\n");
        	messageData.append(QString("--%1\r\n").arg(boundary).toUtf8());
        	messageData.append(QString("Content-Disposition: attachment; filename=\"%1\"\r\n").arg(QFileInfo(fileName).fileName()).toUtf8());
        	messageData.append(QString("Content-Type: %1\r\n").arg(mime.name()).toUtf8());
        	messageData.append("Content-Transfer-Encoding: base64\r\n");
        	messageData.append("\r\n");
        	socket.flush();
        	messageData.append(fileData.toBase64());
        	messageData.append("\r\n");
        	messageData.append(QString("--%1--\r\n").arg(boundary).toUtf8());
        	socket.write(messageData);
        	socket.flush();
        

        But I don't know exactly what the problem is.

        C Offline
        C Offline
        ChrisW67
        wrote on last edited by
        #8

        @razorqhex Your mail data is malformed (see my previous)

        This is what a well-formed SMTP conversation should look like:

        EHLO host.example.com
        MAIL FROM: sender@example.com
        RCPT TO: recipient@example.com
        DATA
        From: sender@example.com
        To: recipient@example.com
        Subject: Test email
        Content-Type: multipart/mixed; boundary="test-boundary"
        
        This is the preamble.  It is to be ignored, though it 
        is a handy place for mail composers to include an 
        explanatory note to non-MIME compliant readers. 
        --test-boundary
        Content-Type: text/plain; charset=utf-8
        
        Body text
        
        --test-boundary
        Content-Disposition: attachment; filename="test.png"
        Content-Type: image/png
        Content-Transfer-Encoding: base64
        
        iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9
        kT1Iw1AUhU/TiiIVBzuoOGSoThZERQQXrUIRKoRaoVUHk5f+QZOGJMXFUXAtOPizWHVwcdbVwVUQ
        BH9AXF2cFF2kxPuSQosYLzzex3n3HN67DxDqZaZZoTFA020zlYiLmeyq2PmKIAYQQAgzMrOMOUlK
        wre+7qmT6i7Gs/z7/qweNWcxICASzzLDtIk3iKc2bYPzPnGEFWWV+Jx41KQLEj9yXfH4jXPBZYFn
        Rsx0ap44QiwW2lhpY1Y0NeJJ4qiq6ZQvZDxWOW9x1spV1rwnf2E4p68sc53WEBJYxBIkiFBQRQll
        2IjRrpNiIUXncR//oOuXyKWQqwRGjgVUoEF2/eB/8Hu2Vn5i3EsKx4GOF8f5GAY6d4FGzXG+jx2n
        cQIEn4ErveWv1IHpT9JrLS16BPRuAxfXLU3ZAy53gP4nQzZlVwrSEvJ54P2MvikL9N0C3Wve3Jrn
        OH0A0jSr5A1wcAiMFCh73efdXe1z+7enOb8fV1pynAvpCcAAAAAJcEhZcwAALiMAAC4jAXilP3YA
        AAAHdElNRQfnAxkBBS96QEB0AAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAA
        AChJREFUSMftzUENAAAIBKDT/p01hQ83KEBNbnUEAoFAIBAIBALBk2ABo8QBP1gd7ycAAAAASUVO
        RK5CYII=
        --test-boundary
        This is the epilogue.  It is also to be ignored.
        
        .
        QUIT
        
        R 1 Reply Last reply
        3
        • C ChrisW67

          @razorqhex Your mail data is malformed (see my previous)

          This is what a well-formed SMTP conversation should look like:

          EHLO host.example.com
          MAIL FROM: sender@example.com
          RCPT TO: recipient@example.com
          DATA
          From: sender@example.com
          To: recipient@example.com
          Subject: Test email
          Content-Type: multipart/mixed; boundary="test-boundary"
          
          This is the preamble.  It is to be ignored, though it 
          is a handy place for mail composers to include an 
          explanatory note to non-MIME compliant readers. 
          --test-boundary
          Content-Type: text/plain; charset=utf-8
          
          Body text
          
          --test-boundary
          Content-Disposition: attachment; filename="test.png"
          Content-Type: image/png
          Content-Transfer-Encoding: base64
          
          iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9
          kT1Iw1AUhU/TiiIVBzuoOGSoThZERQQXrUIRKoRaoVUHk5f+QZOGJMXFUXAtOPizWHVwcdbVwVUQ
          BH9AXF2cFF2kxPuSQosYLzzex3n3HN67DxDqZaZZoTFA020zlYiLmeyq2PmKIAYQQAgzMrOMOUlK
          wre+7qmT6i7Gs/z7/qweNWcxICASzzLDtIk3iKc2bYPzPnGEFWWV+Jx41KQLEj9yXfH4jXPBZYFn
          Rsx0ap44QiwW2lhpY1Y0NeJJ4qiq6ZQvZDxWOW9x1spV1rwnf2E4p68sc53WEBJYxBIkiFBQRQll
          2IjRrpNiIUXncR//oOuXyKWQqwRGjgVUoEF2/eB/8Hu2Vn5i3EsKx4GOF8f5GAY6d4FGzXG+jx2n
          cQIEn4ErveWv1IHpT9JrLS16BPRuAxfXLU3ZAy53gP4nQzZlVwrSEvJ54P2MvikL9N0C3Wve3Jrn
          OH0A0jSr5A1wcAiMFCh73efdXe1z+7enOb8fV1pynAvpCcAAAAAJcEhZcwAALiMAAC4jAXilP3YA
          AAAHdElNRQfnAxkBBS96QEB0AAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAA
          AChJREFUSMftzUENAAAIBKDT/p01hQ83KEBNbnUEAoFAIBAIBALBk2ABo8QBP1gd7ycAAAAASUVO
          RK5CYII=
          --test-boundary
          This is the epilogue.  It is also to be ignored.
          
          .
          QUIT
          
          R Offline
          R Offline
          razorqhex
          wrote on last edited by
          #9

          @ChrisW67, I rewrote the code like this:

          QByteArray boundary = "my_boundary";
          QByteArray message;
          message.append(QString("From: ").toUtf8() + QString(from).toUtf8() + QString("\r\n").toUtf8());
          message.append(QString("To: %1").arg(ui->lEdit_addrFrom->text()).toUtf8() + QString(to).toUtf8() + QString("\r\n").toUtf8());
          message.append("Subject: " + QString(subject).toUtf8() + "\r\n");
          message.append("MIME-Version: 1.0\r\n");
          message.append("Content-Type: multipart/mixed; boundary=" + boundary + "\r\n\r\n");
          
          // Body
          message.append("--" + boundary + "\r\n");
          message.append("Content-Type: text/plain\r\n\r\n");
          message.append(QString(body).toUtf8() + "\r\n\r\n");
          
          // Attachment
          message.append("--" + boundary + "\r\n");
          message.append("Content-Disposition: attachment; filename=\"" + fileInfo.fileName().toUtf8() + "\"\r\n");
          message.append("Content-Type: " + mime.name().toUtf8() + "; name=\"" + fileInfo.fileName().toUtf8() + "\"\r\n");
          message.append("Content-Transfer-Encoding: base64\r\n\r\n");
          message.append(fileData.toBase64() + "\r\n\r\n");
          
          // Completing a message
          message.append("--" + boundary + "--\r\n");
          
          socket.write(message);
          socket.write(".\r\n");
          socket.flush();
          

          And then I get a message with the correct attachment. But it still gets an error in this function:

          //Message
          if (!socket.waitForBytesWritten()) {
          	qDebug() << "Error MESSAGE on SMTP-server";
          	return;
          }
          
          if (!socket.waitForReadyRead()) {
          	qDebug() << "Error";
          	return;
          }
          

          And with all this, the error handler is not called.

          Is it still a mistake in the structure of the message or what? I don't understand anything in this world

          S C 2 Replies Last reply
          0
          • R razorqhex

            @ChrisW67, I rewrote the code like this:

            QByteArray boundary = "my_boundary";
            QByteArray message;
            message.append(QString("From: ").toUtf8() + QString(from).toUtf8() + QString("\r\n").toUtf8());
            message.append(QString("To: %1").arg(ui->lEdit_addrFrom->text()).toUtf8() + QString(to).toUtf8() + QString("\r\n").toUtf8());
            message.append("Subject: " + QString(subject).toUtf8() + "\r\n");
            message.append("MIME-Version: 1.0\r\n");
            message.append("Content-Type: multipart/mixed; boundary=" + boundary + "\r\n\r\n");
            
            // Body
            message.append("--" + boundary + "\r\n");
            message.append("Content-Type: text/plain\r\n\r\n");
            message.append(QString(body).toUtf8() + "\r\n\r\n");
            
            // Attachment
            message.append("--" + boundary + "\r\n");
            message.append("Content-Disposition: attachment; filename=\"" + fileInfo.fileName().toUtf8() + "\"\r\n");
            message.append("Content-Type: " + mime.name().toUtf8() + "; name=\"" + fileInfo.fileName().toUtf8() + "\"\r\n");
            message.append("Content-Transfer-Encoding: base64\r\n\r\n");
            message.append(fileData.toBase64() + "\r\n\r\n");
            
            // Completing a message
            message.append("--" + boundary + "--\r\n");
            
            socket.write(message);
            socket.write(".\r\n");
            socket.flush();
            

            And then I get a message with the correct attachment. But it still gets an error in this function:

            //Message
            if (!socket.waitForBytesWritten()) {
            	qDebug() << "Error MESSAGE on SMTP-server";
            	return;
            }
            
            if (!socket.waitForReadyRead()) {
            	qDebug() << "Error";
            	return;
            }
            

            And with all this, the error handler is not called.

            Is it still a mistake in the structure of the message or what? I don't understand anything in this world

            S Offline
            S Offline
            SimonSchroeder
            wrote on last edited by
            #10

            @razorqhex said in Can't send file via SMTP protocol:

            And then I get a message with the correct attachment. But it still gets an error in this function:

            waitForBytesWritten() has a default value of 30 seconds as a timeout. If your operation takes longer than 30 seconds this function will return false and you'll see "Error MESSAGE on SMTP-server".

            R 1 Reply Last reply
            0
            • S SimonSchroeder

              @razorqhex said in Can't send file via SMTP protocol:

              And then I get a message with the correct attachment. But it still gets an error in this function:

              waitForBytesWritten() has a default value of 30 seconds as a timeout. If your operation takes longer than 30 seconds this function will return false and you'll see "Error MESSAGE on SMTP-server".

              R Offline
              R Offline
              razorqhex
              wrote on last edited by
              #11

              @SimonSchroeder, I know, but the fact is that without any pauses, the waitForBytesWritten () function immediately executes

              S 1 Reply Last reply
              0
              • R razorqhex

                @SimonSchroeder, I know, but the fact is that without any pauses, the waitForBytesWritten () function immediately executes

                S Offline
                S Offline
                SimonSchroeder
                wrote on last edited by
                #12

                @razorqhex Then you should try qDebug() << socket.errorString(); to figure out what's happening.

                R 1 Reply Last reply
                0
                • S SimonSchroeder

                  @razorqhex Then you should try qDebug() << socket.errorString(); to figure out what's happening.

                  R Offline
                  R Offline
                  razorqhex
                  wrote on last edited by
                  #13

                  @SimonSchroeder, this command show me "Unknown error"

                  1 Reply Last reply
                  0
                  • R razorqhex

                    @ChrisW67, I rewrote the code like this:

                    QByteArray boundary = "my_boundary";
                    QByteArray message;
                    message.append(QString("From: ").toUtf8() + QString(from).toUtf8() + QString("\r\n").toUtf8());
                    message.append(QString("To: %1").arg(ui->lEdit_addrFrom->text()).toUtf8() + QString(to).toUtf8() + QString("\r\n").toUtf8());
                    message.append("Subject: " + QString(subject).toUtf8() + "\r\n");
                    message.append("MIME-Version: 1.0\r\n");
                    message.append("Content-Type: multipart/mixed; boundary=" + boundary + "\r\n\r\n");
                    
                    // Body
                    message.append("--" + boundary + "\r\n");
                    message.append("Content-Type: text/plain\r\n\r\n");
                    message.append(QString(body).toUtf8() + "\r\n\r\n");
                    
                    // Attachment
                    message.append("--" + boundary + "\r\n");
                    message.append("Content-Disposition: attachment; filename=\"" + fileInfo.fileName().toUtf8() + "\"\r\n");
                    message.append("Content-Type: " + mime.name().toUtf8() + "; name=\"" + fileInfo.fileName().toUtf8() + "\"\r\n");
                    message.append("Content-Transfer-Encoding: base64\r\n\r\n");
                    message.append(fileData.toBase64() + "\r\n\r\n");
                    
                    // Completing a message
                    message.append("--" + boundary + "--\r\n");
                    
                    socket.write(message);
                    socket.write(".\r\n");
                    socket.flush();
                    

                    And then I get a message with the correct attachment. But it still gets an error in this function:

                    //Message
                    if (!socket.waitForBytesWritten()) {
                    	qDebug() << "Error MESSAGE on SMTP-server";
                    	return;
                    }
                    
                    if (!socket.waitForReadyRead()) {
                    	qDebug() << "Error";
                    	return;
                    }
                    

                    And with all this, the error handler is not called.

                    Is it still a mistake in the structure of the message or what? I don't understand anything in this world

                    C Offline
                    C Offline
                    ChrisW67
                    wrote on last edited by
                    #14

                    @razorqhex This could be because your call to QAbstractSocket::flush() has already written all the bytes to the underlying operating system. You then wait for more bytes to be written but there are none so you time out.

                    R 1 Reply Last reply
                    1
                    • C ChrisW67

                      @razorqhex This could be because your call to QAbstractSocket::flush() has already written all the bytes to the underlying operating system. You then wait for more bytes to be written but there are none so you time out.

                      R Offline
                      R Offline
                      razorqhex
                      wrote on last edited by razorqhex
                      #15

                      @ChrisW67, Yes! You're right! Thank you very much. The error was only that the logic of the code was incorrect.

                      I have corrected the structure of creating a message:

                          QByteArray boundary = "my_boundary";
                          QByteArray message;
                          message.append(QString("From: ").toUtf8() + QString(from).toUtf8() + QString("\r\n").toUtf8());
                      //    message.append(QString("To: %1").arg(ui->lEdit_addrFrom->text()).toUtf8() + QString(to).toUtf8() + QString("\r\n").toUtf8());
                          message.append(QString("To: ").toUtf8() + QString(to).toUtf8() + QString("\r\n").toUtf8());
                          message.append("Subject: " + QString(subject).toUtf8() + "\r\n");
                          message.append("MIME-Version: 1.0\r\n");
                          message.append("Content-Type: multipart/mixed; boundary=" + boundary + "\r\n\r\n");
                      
                          // Body
                          message.append("--" + boundary + "\r\n");
                          message.append("Content-Type: text/plain\r\n\r\n");
                          message.append(QString(body).toUtf8() + "\r\n\r\n");
                      
                          // Attachment
                          message.append("--" + boundary + "\r\n");
                          message.append("Content-Disposition: attachment; filename=\"" + fileInfo.fileName().toUtf8() + "\"\r\n");
                          message.append("Content-Type: " + mime.name().toUtf8() + "; name=\"" + fileInfo.fileName().toUtf8() + "\"\r\n");
                          message.append("Content-Transfer-Encoding: base64\r\n\r\n");
                          message.append(fileData.toBase64() + "\r\n\r\n");
                      
                          // Completing a message
                          message.append("--" + boundary + "--\r\n");
                          //====================================================================================
                      
                          socket.write(message);
                          socket.write(".\r\n");
                      //    socket.flush();
                      

                      And also removed socket.flush(); when sending the MESSAGE command and when sending the QUIT command

                      And now everything works as it should. Once again thank you very much.

                      Now there is only one problem left to fix. Some SMTP servers do not understand Ukrainian and Russian encodings. Incomprehensible letters are shown instead of Cyrillic

                      UPD: I also corrected the encoding.
                      Where is the comment BODY
                      Instead of a line

                      message.append("Content-Type: text/plain\r\n\r\n");
                      

                      Need to add

                      message.append("Content-Type: text/plain; charset=UTF-8\r\n\r\n");
                      

                      And above, where the addressee is formed, you need instead of this line

                      message.append("Content-Type: multipart/mixed; boundary=" + boundary + "\r\n\r\n");
                      

                      Write this line:

                      message.append("Content-Type: multipart/mixed; charset=UTF-8; boundary=" + boundary + "\r\n\r\n");
                      

                      Thank you all for your help :)

                      1 Reply Last reply
                      1
                      • R razorqhex has marked this topic as solved on

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved