From e822e13dc8e7af7f8e2b88e1121798a6d38cccaf Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Wed, 10 May 2023 09:01:30 +0200 Subject: [PATCH] add support for sending emails in Http class --- winixd/utils/http.cpp | 127 +++++++++++++++++++++++++++++++++++++++++- winixd/utils/http.h | 22 +++++++- 2 files changed, 147 insertions(+), 2 deletions(-) diff --git a/winixd/utils/http.cpp b/winixd/utils/http.cpp index c147a00..dceca69 100644 --- a/winixd/utils/http.cpp +++ b/winixd/utils/http.cpp @@ -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; } diff --git a/winixd/utils/http.h b/winixd/utils/http.h index fa43f1e..cc4f27c 100644 --- a/winixd/utils/http.h +++ b/winixd/utils/http.h @@ -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;