I'm using Qt and I recently made a similar application using gmail. Now, I want to send the email from outlook to gmail. EDIT: I just tried sending from outlook to outlook using an app password but still empty email in my outlook inbox... END EDIT Here is my code:
if(file.open(QIODevice::ReadWrite)){ //Writes in the msg.txt
QTextStream stream(&file);
stream << "From: \"Me\" <xxxxxxxxxx#outlook.com>" << endl;
stream << "To: \"Me\" <xxxxxxxxxxxx#gmail.com>" << endl;
stream << "Subject: Subject" << endl;
stream << msg << endl; //msg is just a QString variable
}
QString cmd = "ccurl smtp://smtp-mail.outlook.com:587 -v --mail-from \"xxxxxxxxxxxx#outlook.com\" --mail-rcpt \"xxxxxxxxxxxx#gmail.com\" --ssl -u xxxxxxxxxxxxxx#outlook.com:xxxxxxxxxxxxxx -T \"msg.txt\" -k --anyauth --insecure & pause";
const std::string s = cmd.toStdString();
const char* ccmd = s.c_str();
system(ccmd);
Pause is just used for testing purposes. Also, my .exe is named 'ccurl' and the console that appears doesn't throw any error. I do receive an email but it just says something like (Empty)
---
Email checked by avast....
Thanks for your help!
Ps. Don't tell me to use libcurl instead
You are missing an empty line between the end of the headers and the start of the message body. Without it, the rest of the message is interpreted as if it was still part of the headers.
Also, endl forces a flush in the stream for no good reason, which kills performance when done on files. Just use \n.
Related
I use a mqtt message to send messages like this: mosquitto_pub -t "TOPIC1" -m "ARG1\nARG2\n"
In my C++ application i write:
string payload = reinterpret_cast<char*>(message->payload);
std::istringstream iss(payload);
std::string arg1;
std::getline(iss, arg1);
cout << arg1 << endl;
This gives me ARG1\nARG2\n. What's wrong here?
This is not a C++ problem.
Your problem is that normally \n is not interpreted as new line in by bash for a command line argument. Also mosquitto_pub will not do any interpretation on the input message.
You can force this as follows:
mosquitto_pub -t "TOPIC1" -m $'ARG1\nARG2\n'
How to add Subject to this email?
#include <windows.h>
int main(void){
char* command = "curl smtp://smtp.gmail.com:587 -v --mail-from \"SENDER.EMAIL#gmail.com\" --mail-rcpt \"RECEIVER.EMAIL#gmail.com\" --ssl -u SENDER.EMAIL#gmail.com:PASSWORD -T \"ATTACHMENT.FILE\" -k --anyauth";
WinExec(command, SW_HIDE);
return 0;
}
There are 2 ways to send mail with subject in cURL: Command Line and From C++ code.
Command Line:
The subject can be specified in email data text file "email.txt"
curl smtp://mail.example.com --mail-from myself#example.com --mail-rcpt
receiver#example.com --upload-file email.txt
Here is the tutorial: cURL_SMTP_Command_Line
From C++ code:
In this case you specify Subject in payload_text.
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO_MAIL "\r\n",
"From: " FROM_MAIL "\r\n",
"Cc: " CC_MAIL "\r\n",
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd#"
"rfcpedant.example.org>\r\n",
"Subject: SMTP example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
Here is the example: cURL_SMTP_From_Code
I would like to point you to https://everything.curl.dev/libcurl/libcurl which describes the --libcurl option for the curl command.
When running curl with --libcurl outfile.c, it will save sample code to outfile.c demonstrating how to use libcurl in the same way that the curl command does.
The reason I share this is to help you know how to find out for yourself how to do what you want with libcurl. Hopefully, this will help answer any questions you may have down the road.
I'm developing a RESTful API using Mongoose Web Server. I'm sending a file using
mg_send_file(conn, path, NULL);
but if the file is plain text, or a PDF, it just displays in the browser, instead of forcing the download, which is what I need.
How can I achieve that?
Thanks
--- Update:
I also tried to use
const char* extraHeaders = "Content-Disposition: attachment;
filename=somefilename.txt";
mg_send_file(conn, "somefilename.txt", extraHeaders);
return MG_MORE;
but the connection keeps running, nothing happens.
Final solution was:
const char* extraHeaders = "Content-Disposition: attachment;
filename=\"somefilename.txt\"\r\n";
mg_send_file(conn, "somefilename.txt", extraHeaders);
return MG_MORE;
Note the filename between "", and the \r\n at the end of any extra header.
I wrote a program with Qt to work with cisco ip phone services. I'm using QNetworkAccessManager to post XML objects to phones and QTcpServer's socket with QTextStream to respond to authentication requests (simply writing http headers with "AUTHORIZED" to text stream).
QString cTime = currTime.currentDateTimeUtc().toString("ddd, dd MMM yyyy hh:mm:ss");
QTextStream os(socket); os << "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Date: " + cTime + " GMT\r\n"
"Connection: close\r\n"
"\r\n"
"AUTHORIZED";
The problem is the phones don't accept that response and return <CiscoIPPhoneError Number="4" />.
I used node.js for that before and simply wrote "AUTHORIZED" to http.serverResponse object, but I'm confused now why it doesn't work with Qt
Solved that.
The problem was the "Secure Authentication URL" field was set along with "Authentication url". And what I thought to be GET from phone was "Client hello"...
Cleared "Secure Authentication URL" in CUCM and it works now
I'm just writing a little client side HTTP application. It just sends a GET Request to an IP Camera and then receives a Screenshot in jpeg format.
Now for the implementation of HTTP I am using Boost Asio. So for the first try I oriented pretty much at the sync_client example Boost Asio Sync HTTP Client Example.
Now mainly I'm a bit worried by the separation of Headers and Data.
First I get the first line of the response:
boost::asio::streambuf response;
boost::asio::read_until(*m_Socket, response, "\r\n");
std::istream response_stream(&response);
std::string http_version;
response_stream >> http_version;
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{
std::cout << "Invalid response\n";
return;
}
uint32_t status_code;
response_stream >> status_code;
std::string status_message;
std::getline(response_stream, status_message);
if (status_code != 200) // 200 = status code OK
{
std::cout << "Response returned with status code " << status_code << "\n";
return;
}
Now until here everything is clear to me.I'm reading until first new line and then check the stuff in my buffer.
Now I'm trying to read the second part of the header:
boost::asio::read_until(*m_Socket, response, "\r\n\r\n");
std::string header;
while (std::getline(response_stream, header) && (header != "\r"))
{
std::cout << header << "\n";
}
std::cout << "\n";
Now to this I have some questions:
The while loop is searching until there is a blank line ( the only line where a \r stands all by itself ). Now if I assume that a new line is defined by \r , why do I use \r\n\r\n at boost::asio::read_until ? I mean I would expect wether the one or the other, but both?
If I call the boost::asio::read_until method with \r\r as delimiter it throws an End of File exception. This stands in contrary to what my while loop is searching since this is looking for a \r\r ( since it looks line after line, and every line closes with a \r )
So as you can see Im quite worried how to divide stuff inside my header. It's getting even worser because the boost::asio::read_until call does always read further than the delmiter ( this is actually OK, since it's mentioned in the documentation ), but still it kinda always has the same trail of data ( from the actualy jpeg ), with the same length following.
Maybe someone could enlighten me?
'\r' is the carriage return (CR) character and '\n' is the line-feed (LF) character. HTTP message lines are terminated by "\r\n" (CRLF).
From "HTTP The Definitive Guide":
It is worth pointing out that while the HTTP specification for
terminating lines is CRLF, robust application also should accept just
a line-feed character. Some older or broken HTTP applications do not
always send both the carriage return and line feed.
What seems to be throwing you off is that some line I/O functions (in this case std::getline()) automatically strip the trailing '\n' so you are only seeing the preceding '\r'. I think what you should be doing, is looking for a blank line (rather than a line with only '\r'). And a line that is only '\r' should be considered a blank line.
The "\r\n\r\n" delimiter is used to separate the headers from the actual server's response(which is the JPEG image you are fetching). That's why you're using it; headers are separated by "\r\n".
You should read until "\r\n\r\n". Everything that comes afterwards is the JPEG image. Note that you can guess the length of the file by checking the Content-Length header, or just read until the server closes the socket.