add support for sending emails in Http class

This commit is contained in:
Tomasz Sowa 2023-05-10 09:01:30 +02:00
parent cc2c008bfd
commit e822e13dc8
Signed by: tomasz.sowa
GPG Key ID: 662CC1438638588B
2 changed files with 147 additions and 2 deletions

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2010-2022, Tomasz Sowa
* Copyright (c) 2010-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -82,6 +82,10 @@ Http & Http::begin()
client_key = nullptr;
client_cert_utf8.clear();
client_key_utf8.clear();
smtp_recipients = nullptr;
smtp_from = nullptr;
username = nullptr;
password = nullptr;
return *this;
}
@ -90,6 +94,10 @@ Http & Http::begin()
Http::~Http()
{
/*
* IMPROVEME
* free http_headers and smtp_recipients if exists
*/
uninitialize_curl();
}
@ -160,8 +168,32 @@ Http & Http::add_header(const wchar_t * str, size_t len)
}
Http & Http::add_recipient(const char * recipient)
{
smtp_recipients = curl_slist_append(smtp_recipients, recipient);
return *this;
}
Http & Http::add_recipient(const std::string & recipient)
{
return add_recipient(recipient.c_str());
}
Http & Http::add_recipient(const wchar_t * recipient)
{
pt::wide_to_utf8(recipient, temp_header_ascii);
smtp_recipients = curl_slist_append(smtp_recipients, temp_header_ascii.c_str());
return *this;
}
Http & Http::add_recipient(const std::wstring & recipient)
{
return add_recipient(recipient.c_str());
}
Http & Http::add_headers(pt::Space * headers)
{
@ -360,6 +392,66 @@ bool Http::put(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out,
}
bool Http::send_mail(const wchar_t * smtp_url, const wchar_t * from, const std::string & in, pt::WTextStream & out, bool clear_stream)
{
std::string url_ascii;
pt::TextStream out_stream;
if( clear_stream )
{
out.clear();
}
pt::wide_to_utf8(smtp_url, url_ascii);
smtp_from = from;
bool status = fetch_internal(Method::method_smtp, url_ascii.c_str(), &in, out_stream);
out << out_stream;
return status;
}
bool Http::send_mail(const wchar_t * smtp_url, const wchar_t * from, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream)
{
std::string in_ascii;
in.to_str(in_ascii);
return send_mail(smtp_url, from, in_ascii, out, clear_stream);
}
Http & Http::set_username(const wchar_t * username)
{
this->username = username;
return *this;
}
Http & Http::set_password(const wchar_t * password)
{
this->password = password;
return *this;
}
Http & Http::set_username(const std::wstring & username)
{
return set_username(username.c_str());
}
Http & Http::set_password(const std::wstring & password)
{
return set_password(password.c_str());
}
long Http::get_status()
{
long status = -1;
@ -391,6 +483,12 @@ void Http::reset_headers()
curl_slist_free_all(http_headers);
http_headers = nullptr;
}
if( smtp_recipients )
{
curl_slist_free_all(smtp_recipients);
smtp_recipients = nullptr;
}
}
@ -623,6 +721,18 @@ bool Http::fetch_internal(Method method, const char * url, const std::string * i
curl_easy_setopt(curl, CURLOPT_SSLKEY, client_key_utf8.c_str());
}
if( username )
{
pt::wide_to_utf8(username, temp_header_ascii);
curl_easy_setopt(curl, CURLOPT_USERNAME, temp_header_ascii.c_str());
}
if( password )
{
pt::wide_to_utf8(password, temp_header_ascii);
curl_easy_setopt(curl, CURLOPT_PASSWORD, temp_header_ascii.c_str());
}
// block the Expect: 100-continue header
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect
// https://httpwg.org/specs/rfc7231.html#header.expect
@ -689,6 +799,21 @@ void Http::put_method(Method & method)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "OPTIONS");
break;
case Method::method_smtp:
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
if( smtp_from )
{
pt::wide_to_utf8(smtp_from, temp_header_ascii);
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, temp_header_ascii.c_str());
}
if( smtp_recipients )
{
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, smtp_recipients);
}
break;
default:
break;
}

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2010-2022, Tomasz Sowa
* Copyright (c) 2010-2023, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -61,6 +61,7 @@ public:
method_patch,
method_delete,
method_options,
method_smtp,
};
Http();
@ -265,6 +266,21 @@ public:
bool put(const std::wstring & url, const std::string & in, pt::WTextStream & out, bool clear_stream = true);
bool put(const wchar_t * url, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream = true);
Http & add_recipient(const char * recipient);
Http & add_recipient(const std::string & recipient);
Http & add_recipient(const wchar_t * recipient);
Http & add_recipient(const std::wstring & recipient);
bool send_mail(const wchar_t * smtp_url, const wchar_t * from, const std::string & in, pt::WTextStream & out, bool clear_stream = true);
bool send_mail(const wchar_t * smtp_url, const wchar_t * from, pt::WTextStream & in, pt::WTextStream & out, bool clear_stream = true);
Http & set_username(const wchar_t * username);
Http & set_password(const wchar_t * password);
Http & set_username(const std::wstring & username);
Http & set_password(const std::wstring & password);
/*
* return the last http status
*/
@ -281,6 +297,7 @@ private:
size_t read_function_index;
const std::string * read_function_input;
curl_slist * http_headers;
curl_slist * smtp_recipients;
pt::Space * additional_space_headers_to_send;
const char * additional_string_headers_to_send;
const wchar_t * additional_wstring_headers_to_send;
@ -301,6 +318,9 @@ private:
const wchar_t * client_key;
std::string client_cert_utf8;
std::string client_key_utf8;
const wchar_t * smtp_from;
const wchar_t * username;
const wchar_t * password;
std::wstring temp_header;
std::string temp_header_ascii;